diff options
Diffstat (limited to 'pages')
-rw-r--r-- | pages/options/options.html | 376 | ||||
-rw-r--r-- | pages/options/options.js | 225 | ||||
-rw-r--r-- | pages/popup/popup.html | 149 | ||||
-rw-r--r-- | pages/popup/popup.js | 81 | ||||
-rw-r--r-- | pages/styles.css | 149 |
5 files changed, 644 insertions, 336 deletions
diff --git a/pages/options/options.html b/pages/options/options.html index 317f8145..ca6429f1 100644 --- a/pages/options/options.html +++ b/pages/options/options.html @@ -12,124 +12,136 @@ <body> <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> + <button class="tablinks" id="general-tab" data-localize="__MSG_generalTab__">General</button> + <button class="tablinks" id="advanced-tab" data-localize="__MSG_advancedTab__">Advanced</button> + <button class="tablinks" id="exceptions-tab" data-localize="__MSG_exceptionsTab__">Exceptions</button> </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 class="settings-block"> + <table class="option" aria-label="Toggle Nitter redirects"> + <tbody> + <tr> + <td> + <h1 data-localize="__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 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 class="settings-block"> + <table class="option" aria-label="Toggle Invidious redirects"> + <tbody> + <tr> + <td> + <h1 data-localize="__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 Bibliogram redirects"> - <h1>Bibliogram Redirects</h1> - <input aria-hidden="true" id="disable-bibliogram" type="checkbox" checked> - <label for="disable-bibliogram" class="checkbox-label"> - </label> + <section class="settings-block"> + <table class="option" aria-label="Toggle Bibliogram redirects"> + <tbody> + <tr> + <td> + <h1 data-localize="__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-localize="__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-localize="__MSG_nitterInstance__">Nitter Instance</h1> + <div class="autocomplete"> + <input id="nitter-instance" type="url" name="nitter-instance" placeholder="https://nitter.net"> </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> + <section class="settings-block"> + <h1 data-localize="__MSG_invidiousInstance__">Invidious Instance</h1> + <div class="autocomplete"> + <input id="invidious-instance" type="url" placeholder="https://invidio.us"> </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.services"> - <option value="https://nitter.13ad.de"> - <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"> - </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://invidious.fdn.fr"> - <option value="https://invidious.13ad.de"> - <option value="https://watch.nettohikari.com"> - <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="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://bibliogram.nixnet.services"> - <option value="https://bibliogram.hamster.dance"> - <option value="https://insta.maisputain.ovh"> - <option value="https://bibliogram.ggc-project.de"> - </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 class="settings-block"> + <h1 data-localize="__MSG_bibliogramInstance__">Bibliogram Instance</h1> + <div class="autocomplete"> + <input id="bibliogram-instance" type="url" placeholder="https://bibliogram.art"> + </div> </section> + <sections class="settings-block"> + <h1 data-localize="__MSG_osmInstance__">OpenStreetMap Instance</h1> + <div class="autocomplete"> + <input id="osm-instance" type="url" placeholder="https://openstreetmap.org"> + </div> + </sections> </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 class="settings-block"> + <table class="option" aria-label="Always proxy videos through Invidious"> + <tbody> + <tr> + <td> + <h1 data-localize="__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="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 class="settings-block"> + <table class="option" aria-label="Only redirect embedded video to Invidious"> + <tbody> + <tr> + <td> + <h1 data-localize="__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="options settings_block"> - <h1>Invidious Video Quality</h1> + <section class="settings-block"> + <h1 data-localize="__MSG_videoQuality__">Invidious Video Quality</h1> <select id="video-quality"> <option value="">Default</option> <option value="hd720">720p</option> @@ -137,48 +149,138 @@ <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 class="settings-block"> + <table class="option" aria-label="Invidious dark mode aways on"> + <tbody> + <tr> + <td> + <h1 data-localize="__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="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 class="settings-block"> + <h1 data-localize="__MSG_invidiousVolume__">Invidious Volume</h1> + <input id="invidious-volume" name="invidious-volume" type="range" min="0" max="100" step="1"> </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 class="settings-block"> + <h1 data-localize="__MSG_invidiousPlayerStyle__">Invidious Player Style</h1> + <select id="invidious-player-style"> + <option value="invidious">Invidious</option> + <option value="youtube">YouTube</option> + </select> + </section> + <section class="settings-block"> + <h1 data-localize="__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-localize="__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-localize="__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-localize="__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="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> + <div id="exceptions" class="tabcontent"> + <section class="settings-block" data-localize="__MSG_exceptionsDescription__"> + <p> + Enter a URL or Regular Expression to be excluded from redirects. + </p> + <p> + All requests for or initiating from a URL that matches your exception + will be excluded from redirects. + </p> + <p> + <b>Note -</b> Supports JavaScript regular expressions, excluding + the enclosing forward slashes. + </p> + </section> + <section class="settings-block"> + <table class="exceptions option"> + <tbody> + <tr> + <td> + <h1 data-localize="__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="whitelist-items"></ul> + <ul id="exceptions-items"></ul> </div> <script src="./options.js"></script> - + <script src="../../assets/javascript/localise.js"></script> </body> -</html> +</html> \ No newline at end of file diff --git a/pages/options/options.js b/pages/options/options.js index 5e25a495..19f9bba7 100644 --- a/pages/options/options.js +++ b/pages/options/options.js @@ -1,5 +1,55 @@ 'use strict'; +const nitterInstances = [ + 'https://nitter.net', + 'https://nitter.snopyta.org', + 'https://nitter.42l.fr', + 'https://nitter.nixnet.services', + 'https://nitter.13ad.de', + 'https://nitter.pussthecat.org', + 'https://nitter.mastodont.cat', + 'https://nitter.dark.fail', + 'https://nitter.tedomum.net', + 'https://t.maisputain.ovh', + 'http://3nzoldnxplag42gqjs23xvghtzf6t6yzssrtytnntc6ppc7xxuoneoad.onion', + 'http://nitter.l4qlywnpwqsluw65ts7md3khrivpirse744un3x7mlskqauz5pyuzgqd.onion' +]; +const invidiousInstances = [ + 'https://invidio.us', + 'https://invidious.snopyta.org', + 'https://invidious.fdn.fr', + 'https://invidious.13ad.de', + 'https://watch.nettohikari.com', + 'https://yewtu.be', + 'https://yt.maisputain.ovh', + 'https://invidious.toot.koeln', + 'https://invidious.ggc-project.de', + 'http://kgg2m7yk5aybusll.onion', + 'http://axqzx4s6s54s32yentfqojs3x5i7faxza6xo3ehd4bzzsg2ii4fv2iid.onion', + 'http://fz253lmuao3strwbfbmx46yu7acac2jz27iwtorgmbqlkurlclmancad.onion', + 'http://qklhadlycap4cnod.onion', + 'http://c7hqkpkpemu6e7emz5b4vyz7idjgdvgaaa3dyimmeojqbgpea3xqjoid.onion', + 'http://mfqczy4mysscub2s.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'); @@ -14,24 +64,35 @@ 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; +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 exceptions; window.browser = window.browser || window.chrome; -function prependWhitelistItem(item, index) { +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')); + li.appendChild(button); + 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', () => { - li.remove(); - whitelist.splice(index, 1); + exceptions.splice(index, 1); browser.storage.sync.set({ - whitelist: whitelist + exceptions: exceptions }); + li.remove(); }); - li.appendChild(button); - document.getElementById('whitelist-items').prepend(li); } browser.storage.sync.get( @@ -48,9 +109,13 @@ browser.storage.sync.get( 'onlyEmbeddedVideo', 'videoQuality', 'removeTwitterSW', - 'whitelist', 'invidiousDarkMode', - 'persistInvidiousPrefs' + 'persistInvidiousPrefs', + 'invidiousVolume', + 'invidiousPlayerStyle', + 'invidiousSubtitles', + 'invidiousAutoplay', + 'exceptions' ], result => { nitterInstance.value = result.nitterInstance || ''; @@ -67,8 +132,12 @@ browser.storage.sync.get( 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; + invidiousPlayerStyle.value = result.invidiousPlayerStyle; + invidiousSubtitles.value = result.invidiousSubtitles || ''; + invidiousAutoplay.checked = !result.invidiousAutoplay; } ); @@ -92,22 +161,27 @@ document.getElementById('general-tab').addEventListener( document.getElementById('advanced-tab').addEventListener( 'click', openTab.bind(null, 'advanced') ); -document.getElementById('whitelist-tab').addEventListener( - 'click', openTab.bind(null, 'whitelist') +document.getElementById('exceptions-tab').addEventListener( + 'click', openTab.bind(null, 'exceptions') ); 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 }); + prependExceptionsItem(value, exceptions.indexOf(value)); input.value = ''; } catch (error) { input.setCustomValidity('Invalid RegExp'); @@ -117,8 +191,8 @@ function addToWhitelist() { } } -document.getElementById('add-to-whitelist').addEventListener( - 'click', addToWhitelist +document.getElementById('add-to-exceptions').addEventListener( + 'click', addToExceptions ); function debounce(func, wait, immediate) { @@ -231,3 +305,112 @@ invidiousDarkMode.addEventListener('change', event => { persistInvidiousPrefs.addEventListener('change', event => { browser.storage.sync.set({ persistInvidiousPrefs: event.target.checked }); }); + +let invidiousVolumeChange = debounce(() => { + if (invidiousInstance.checkValidity()) { + 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 }); +}); + + +function autocomplete(input, list) { + let currentFocus; + input.addEventListener("focus", (e) => { + showOptions(e); + }); + 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(e) { + let a, b, i, val = e.target.value; + closeAllLists(); + a = document.createElement("div"); + a.setAttribute("id", e.target.id + "autocomplete-list"); + a.setAttribute("class", "autocomplete-items"); + e.target.parentNode.appendChild(a); + for (i = 0; i < list.length; i++) { + if (list[i].toLowerCase().indexOf(val.toLowerCase()) > -1) { + b = document.createElement("div"); + b.innerHTML = "<strong>" + list[i].substr(0, val.length) + "</strong>"; + b.innerHTML += list[i].substr(val.length); + b.innerHTML += "<input type='hidden' value='" + list[i] + "'>"; + b.addEventListener("click", function (e) { + input.value = e.target.getElementsByTagName("input")[0].value; + input.dispatchEvent(new Event('input')); + closeAllLists(); + }); + a.appendChild(b); + } + } + } + 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); +}) diff --git a/pages/popup/popup.html b/pages/popup/popup.html index 45a88052..1ce7eb01 100644 --- a/pages/popup/popup.html +++ b/pages/popup/popup.html @@ -11,107 +11,88 @@ <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> + <img src="../../assets/images/icon128.png" alt="Privacy Redirect logo"> + <h1><span data-localize="__MSG_privacy__" class="privacy">Privacy</span><br><span + data-localize="__MSG_redirect__">Redirect</span></h1> </div> <div class="version"> <span>Version: <span id="version"></span></span> </div> </header> - <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 class="settings-block"> + <table class="option" aria-label="Toggle Nitter redirects"> + <tbody> + <tr> + <td> + <h1 data-localize="__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 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 class="settings-block"> + <table class="option" aria-label="Toggle Invidious redirects"> + <tbody> + <tr> + <td> + <h1 data-localize="__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 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 class="settings-block"> + <table class="option" aria-label="Toggle Bibliogram redirects"> + <tbody> + <tr> + <td> + <h1 data-localize="__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 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 class="settings-block"> + <table class="option" aria-label="Toggle OpenStreetMap redirects"> + <tbody> + <tr> + <td> + <h1 data-localize="__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"> - <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.services"> - <option value="https://nitter.13ad.de"> - <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"> - </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://invidious.fdn.fr"> - <option value="https://invidious.13ad.de"> - <option value="https://watch.nettohikari.com"> - <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="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://bibliogram.nixnet.services"> - <option value="https://bibliogram.hamster.dance"> - <option value="https://insta.maisputain.ovh"> - <option value="https://bibliogram.ggc-project.de"> - </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 class="settings-block"> </section> <footer> <a class="button" id="more-options"> - <span>More Options </span> + <span data-localize="__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' /> @@ -124,7 +105,7 @@ </footer> <script src="./popup.js"></script> - + <script src="../../assets/javascript/localise.js"></script> </body> </html> \ No newline at end of file diff --git a/pages/popup/popup.js b/pages/popup/popup.js index 66842c75..2e8ec491 100644 --- a/pages/popup/popup.js +++ b/pages/popup/popup.js @@ -1,9 +1,5 @@ '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'); @@ -14,20 +10,12 @@ window.browser = window.browser || window.chrome; browser.storage.sync.get( [ - 'nitterInstance', - 'invidiousInstance', - 'bibliogramInstance', - 'osmInstance', 'disableNitter', 'disableInvidious', 'disableBibliogram', 'disableOsm' ], result => { - 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; @@ -37,75 +25,6 @@ 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 => { browser.storage.sync.set({ disableNitter: !event.target.checked }); }); diff --git a/pages/styles.css b/pages/styles.css index d9a7e5df..dd88a65c 100644 --- a/pages/styles.css +++ b/pages/styles.css @@ -75,7 +75,7 @@ header .version { h1 { font-size: 14px; - margin: var(--space) auto; + margin: 7px auto; } i { @@ -122,7 +122,18 @@ 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); @@ -156,12 +167,12 @@ input:checked+label:after { 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; } @@ -243,32 +254,37 @@ input:invalid { 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); 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; + margin: 20px 20px 0 20px; } li { @@ -276,7 +292,7 @@ li { padding: 20px 0px 20px 20px; } -#whitelist-items button { +#exceptions-items button { float: right; margin-right: -5px; border: var(--active) solid 1px; @@ -285,6 +301,7 @@ li { font-weight: bold; cursor: pointer; border-radius: 50%; + padding: 2px 2px 0px 2px; } .button svg { @@ -292,6 +309,109 @@ li { width: 18px; } +.autocomplete { + position: relative; + display: inline-block; + width: 100%; +} + +.autocomplete input { + background: url(../assets/images/chevron-down.svg) right no-repeat; +} + +.autocomplete-items { + position: absolute; + border: 1px solid var(--dark); + border-bottom: none; + border-top: none; + z-index: 99; + top: 100%; + left: 0; + right: 0; + overflow: auto; + max-height: 175px; +} + +.autocomplete-items div { + padding: 10px; + cursor: pointer; + background-color: var(--darker); + border-bottom: 1px solid var(--dark); +} + +.autocomplete-items div:hover { + background-color: var(--active); +} + +.autocomplete-active { + background-color: var(--active); + color: var(--lighter); +} + +.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; + box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; + background: var(--light); + border-radius: 1.3px; + border: 0.2px solid #010101; +} + +input[type=range]::-webkit-slider-thumb { + box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; + border: 1px solid #000000; + 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(--light); +} + +input[type=range]::-moz-range-track { + width: 100%; + height: 8.4px; + cursor: pointer; + box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; + background: var(--light); + border-radius: 1.3px; + border: 0.2px solid #010101; +} + +input[type=range]::-moz-range-thumb { + box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; + border: 1px solid #000000; + height: 36px; + width: 16px; + border-radius: 3px; + background: var(--active); + cursor: pointer; +} + @media (prefers-color-scheme: dark) { body.popup, header, h1, input, select, div.tabcontent, button.tablinks.active { @@ -311,7 +431,6 @@ li { color: var(--text-main); opacity: 0.7; } - } @media (prefers-color-scheme: light) { @@ -347,4 +466,8 @@ li { button.tablinks.active { border-bottom: solid 1px var(--lighter); } + + .autocomplete-items div { + background-color: var(--light); + } } |