about summary refs log tree commit diff stats
path: root/src/pages/options/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/pages/options/widgets')
-rw-r--r--src/pages/options/widgets/general.js225
-rw-r--r--src/pages/options/widgets/general.pug167
-rw-r--r--src/pages/options/widgets/imgur.js52
-rw-r--r--src/pages/options/widgets/imgur.pug32
-rw-r--r--src/pages/options/widgets/instagram.js42
-rw-r--r--src/pages/options/widgets/instagram.pug27
-rw-r--r--src/pages/options/widgets/lbry.js43
-rw-r--r--src/pages/options/widgets/lbry.pug26
-rw-r--r--src/pages/options/widgets/maps.js32
-rw-r--r--src/pages/options/widgets/maps.pug23
-rw-r--r--src/pages/options/widgets/medium.js42
-rw-r--r--src/pages/options/widgets/medium.pug26
-rw-r--r--src/pages/options/widgets/peertube.js40
-rw-r--r--src/pages/options/widgets/peertube.pug26
-rw-r--r--src/pages/options/widgets/reddit.js90
-rw-r--r--src/pages/options/widgets/reddit.pug42
-rw-r--r--src/pages/options/widgets/search.js142
-rw-r--r--src/pages/options/widgets/search.pug69
-rw-r--r--src/pages/options/widgets/sendTargets.js43
-rw-r--r--src/pages/options/widgets/sendTargets.pug26
-rw-r--r--src/pages/options/widgets/tiktok.js53
-rw-r--r--src/pages/options/widgets/tiktok.pug26
-rw-r--r--src/pages/options/widgets/translate.js75
-rw-r--r--src/pages/options/widgets/translate.pug40
-rw-r--r--src/pages/options/widgets/twitter.js53
-rw-r--r--src/pages/options/widgets/twitter.pug26
-rw-r--r--src/pages/options/widgets/wikipedia.js51
-rw-r--r--src/pages/options/widgets/wikipedia.pug32
-rw-r--r--src/pages/options/widgets/youtube.js161
-rw-r--r--src/pages/options/widgets/youtube.pug73
-rw-r--r--src/pages/options/widgets/youtubeMusic.js23
-rw-r--r--src/pages/options/widgets/youtubeMusic.pug17
32 files changed, 1845 insertions, 0 deletions
diff --git a/src/pages/options/widgets/general.js b/src/pages/options/widgets/general.js
new file mode 100644
index 00000000..c810fb8a
--- /dev/null
+++ b/src/pages/options/widgets/general.js
@@ -0,0 +1,225 @@
+"use strict";
+window.browser = window.browser || window.chrome;
+
+import utils from "../../../assets/javascripts/utils.js";
+import generalHelper from "../../../assets/javascripts/general.js";
+
+import youtubeHelper from "../../../assets/javascripts/youtube/youtube.js";
+import youtubeMusicHelper from "../../../assets/javascripts/youtubeMusic.js";
+import twitterHelper from "../../../assets/javascripts/twitter.js";
+import instagramHelper from "../../../assets/javascripts/instagram.js";
+import redditHelper from "../../../assets/javascripts/reddit.js";
+import searchHelper from "../../../assets/javascripts/search.js";
+import translateHelper from "../../../assets/javascripts/translate/translate.js";
+import mapsHelper from "../../../assets/javascripts/maps.js";
+import wikipediaHelper from "../../../assets/javascripts/wikipedia.js";
+import mediumHelper from "../../../assets/javascripts/medium.js";
+import imgurHelper from "../../../assets/javascripts/imgur.js";
+import tiktokHelper from "../../../assets/javascripts/tiktok.js";
+import sendTargetsHelper from "../../../assets/javascripts/sendTargets.js";
+import peertubeHelper from "../../../assets/javascripts/peertube.js";
+import lbryHelper from "../../../assets/javascripts/lbry.js";
+
+let updateInstancesElement = document.getElementById("update-instances");
+updateInstancesElement.addEventListener("click", () => {
+  let oldHtml = updateInstancesElement.innerHTML
+  updateInstancesElement.innerHTML = '...';
+  if (utils.updateInstances()) {
+    updateInstancesElement.innerHTML = 'Done!';
+    new Promise(resolve => setTimeout(resolve, 1500)).then( // sleep 1500ms
+      () => updateInstancesElement.innerHTML = oldHtml
+    )
+  }
+  else
+    updateInstancesElement.innerHTML = 'Failed Miserabely';
+});
+
+let exportSettingsElement = document.getElementById("export-settings");
+
+function exportSettings() {
+  browser.storage.local.get(
+    null,
+    result => {
+      let resultString = JSON.stringify(result, null, '  ');
+      exportSettingsElement.href = 'data:application/json;base64,' + btoa(resultString);
+      exportSettingsElement.download = 'libredirect-settings.json';
+    }
+  );
+}
+exportSettings();
+
+browser.storage.onChanged.addListener(exportSettings);
+
+let importSettingsElement = document.getElementById("import-settings");
+let importSettingsElementText = document.getElementById('import_settings_text');
+importSettingsElement.addEventListener("change",
+  () => {
+    let file = importSettingsElement.files[0];
+    const reader = new FileReader();
+    reader.readAsText(file);
+    reader.onload = async () => {
+      const data = JSON.parse(reader.result)
+      if (
+        "theme" in data &&
+        "disableImgur" in data &&
+        "cloudflareList" in data &&
+        "imgurRedirects" in data
+      ) {
+        console.log('importing a valid file...');
+        await browser.storage.local.set({ ...data })
+        location.reload();
+      } else
+        importError()
+    }
+    reader.onerror = error => importError();
+  }
+);
+function importError() {
+  const oldHTML = importSettingsElementText.innerHTML;
+  importSettingsElementText.innerHTML = '<span style="color:red;">Error!</span>';
+  setTimeout(() => importSettingsElementText.innerHTML = oldHTML, 1000);
+}
+
+document.getElementById("reset-settings").addEventListener("click",
+  async () => {
+    await browser.storage.local.clear();
+    fetch('/instances/blocklist.json').then(response => response.text()).then(async data => {
+      await browser.storage.local.set({ cloudflareList: JSON.parse(data) })
+      await generalHelper.initDefaults();
+      await youtubeHelper.initDefaults();
+      await youtubeMusicHelper.initDefaults();
+      await twitterHelper.initDefaults();
+      await instagramHelper.initDefaults();
+      await mapsHelper.initDefaults();
+      await searchHelper.initDefaults();
+      await translateHelper.initDefaults();
+      await mediumHelper.initDefaults();
+      await redditHelper.initDefaults();
+      await wikipediaHelper.initDefaults();
+      await imgurHelper.initDefaults();
+      await tiktokHelper.initDefaults();
+      await sendTargetsHelper.initDefaults();
+      await peertubeHelper.initDefaults();
+      await lbryHelper.initDefaults();
+      location.reload();
+    })
+  }
+);
+
+let autoRedirectElement = document.getElementById("auto-redirect")
+autoRedirectElement.addEventListener("change",
+  event => browser.storage.local.set({ autoRedirect: event.target.checked })
+);
+
+let themeElement = document.getElementById("theme");
+themeElement.addEventListener("change", event => {
+  const value = event.target.options[theme.selectedIndex].value;
+  browser.storage.local.set({ theme: value });
+  location.reload();
+})
+
+let nameCustomInstanceInput = document.getElementById("exceptions-custom-instance");
+let instanceTypeElement = document.getElementById("exceptions-custom-instance-type");
+let instanceType = "url"
+
+let popupFrontends;
+for (const frontend of generalHelper.allPopupFrontends)
+  document.getElementById(frontend).addEventListener("change",
+    event => {
+      if (event.target.checked && !popupFrontends.includes(frontend))
+        popupFrontends.push(frontend)
+      else if (popupFrontends.includes(frontend)) {
+        var index = popupFrontends.indexOf(frontend);
+        if (index !== -1) popupFrontends.splice(index, 1);
+      }
+      browser.storage.local.set({ popupFrontends })
+    }
+  )
+
+
+browser.storage.local.get(
+  [
+    'theme',
+    'autoRedirect',
+    'exceptions'
+  ],
+  r => {
+    autoRedirectElement.checked = r.autoRedirect;
+    themeElement.value = r.theme;
+    instanceTypeElement.addEventListener("change",
+      event => {
+        instanceType = event.target.options[instanceTypeElement.selectedIndex].value
+        if (instanceType == 'url') {
+          nameCustomInstanceInput.setAttribute("type", "url");
+          nameCustomInstanceInput.setAttribute("placeholder", "https://www.google.com");
+        }
+        else if (instanceType == 'regex') {
+          nameCustomInstanceInput.setAttribute("type", "text");
+          nameCustomInstanceInput.setAttribute("placeholder", "https?:\/\/(www\.|)youtube\.com\/");
+        }
+      }
+    )
+    let exceptionsCustomInstances = r.exceptions;
+    function calcExceptionsCustomInstances() {
+      document.getElementById("exceptions-custom-checklist").innerHTML =
+        [...exceptionsCustomInstances.url, ...exceptionsCustomInstances.regex].map(
+          (x) => `<div>
+                      ${x}
+                      <button class="add" id="clear-${x}">
+                        <svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 0 24 24" width="20px"
+                        fill="currentColor">
+                          <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
+                        </svg>
+                      </button>
+                    </div>
+                    <hr>`
+        ).join('\n');
+
+      for (const x of [...exceptionsCustomInstances.url, ...exceptionsCustomInstances.regex]) {
+        document.getElementById(`clear-${x}`).addEventListener("click",
+          () => {
+            console.log(x);
+            let index;
+            index = exceptionsCustomInstances.url.indexOf(x);
+            if (index > -1)
+              exceptionsCustomInstances.url.splice(index, 1);
+            else {
+              index = exceptionsCustomInstances.regex.indexOf(x);
+              if (index > -1)
+                exceptionsCustomInstances.regex.splice(index, 1);
+            }
+            browser.storage.local.set({ exceptions: exceptionsCustomInstances })
+            calcExceptionsCustomInstances();
+          });
+      }
+    }
+    calcExceptionsCustomInstances();
+    document.getElementById("custom-exceptions-instance-form").addEventListener("submit", (event) => {
+      event.preventDefault();
+
+      let val
+      if (instanceType == 'url') {
+        if (nameCustomInstanceInput.validity.valid) {
+          let url = new URL(nameCustomInstanceInput.value);
+          val = `${url.protocol}//${url.host}`
+          if (!exceptionsCustomInstances.url.includes(val)) exceptionsCustomInstances.url.push(val)
+        }
+      } else if (instanceType == 'regex') {
+        val = nameCustomInstanceInput.value
+        if (val.trim() != '' && !exceptionsCustomInstances.regex.includes(val)) exceptionsCustomInstances.regex.push(val)
+      }
+      if (val) {
+        browser.storage.local.set({ exceptions: exceptionsCustomInstances })
+        nameCustomInstanceInput.value = '';
+      }
+      calcExceptionsCustomInstances();
+    })
+
+    browser.storage.local.get('popupFrontends',
+      r => {
+        popupFrontends = r.popupFrontends;
+        for (const frontend of generalHelper.allPopupFrontends)
+          document.getElementById(frontend).checked = popupFrontends.includes(frontend);
+      }
+    )
+  })
diff --git a/src/pages/options/widgets/general.pug b/src/pages/options/widgets/general.pug
new file mode 100644
index 00000000..c1fcc459
--- /dev/null
+++ b/src/pages/options/widgets/general.pug
@@ -0,0 +1,167 @@
+section#general_page.option-block
+    .some-block.option-block
+        h1(data-localise="__MSG_general__") General
+    hr
+
+    .some-block.option-block
+        h4(data-localise="__MSG_theme__") Theme
+        select#theme
+            option(value="DEFAULT" data-localise="__MSG_system__") System
+            option(value="light" data-localise="__MSG_light__") Light
+            option(value="dark" data-localise="__MSG_dark__") Dark
+
+    .some-block.option-block
+        h4(data-localise="__MSG_autoRedirect__")
+        input#auto-redirect(type="checkbox")
+
+    .some-block.option-block
+        h4(data-localise="__MSG_exceptions__")
+
+    form#custom-exceptions-instance-form
+        .some-block.option-block
+            .some-block(style="padding:0;")
+                input#exceptions-custom-instance(placeholder="https://www.google.com" type="url")
+                |&nbsp;
+                select#exceptions-custom-instance-type
+                    option(value="url") URL
+                    option(value="regex") Regex
+                |&nbsp;
+            button#exceptions-add-instance.add(type="submit")
+                svg(xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 0 24 24" width="20px" fill="currentColor")
+                    path(d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z")
+
+    #exceptions-custom-checklist.checklist
+
+    .buttons.buttons-inline
+        a#update-instances.button.button-inline
+            svg(xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor")
+                path(d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z")
+            x(data-localise="__MSG_updateInstances__") Update Instances
+
+        |&nbsp; &nbsp;
+
+        label#import_settings_text.button.button-inline(for="import-settings") 
+            svg(xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor")
+                path(d="M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z")
+            |&nbsp;
+            x(data-localise="__MSG_importSettings__") Import Settings
+        input#import-settings.button.button-inline(type="file" style="display:none;")
+
+        |&nbsp; &nbsp;
+
+        a#export-settings.button.button-inline
+            svg(xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor")
+                path(d="M10.09 15.59L11.5 17l5-5-5-5-1.41 1.41L12.67 11H3v2h9.67l-2.58 2.59zM19 3H5c-1.11 0-2 .9-2 2v4h2V5h14v14H5v-4H3v4c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z")
+            |&nbsp;
+            x(data-localise="__MSG_exportSettings__") Export Settings
+
+        |&nbsp; &nbsp;
+
+        a#reset-settings.button.button-inline
+            svg(xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor")
+                path(d="M12,5V2L8,6l4,4V7c3.31,0,6,2.69,6,6c0,2.97-2.17,5.43-5,5.91v2.02c3.95-0.49,7-3.85,7-7.93C20,8.58,16.42,5,12,5z")
+                path(d="M6,13c0-1.65,0.67-3.15,1.76-4.24L6.34,7.34C4.9,8.79,4,10.79,4,13c0,4.08,3.05,7.44,7,7.93v-2.02 C8.17,18.43,6,15.97,6,13z")
+            x(data-localise="__MSG_resetSettings__") Reset Settings
+    hr
+
+    .some-block.option-block
+        h4(data-localise="__MSG_customPopup__") Customize Popup
+
+    #popup-frontends-checklist.checklist-popup
+        div
+            div
+                img(src="../../../assets/images/youtube-icon.png")
+                x(data-localise="__MSG_youtube__") YouTube
+            input#youtube(type="checkbox")
+        div
+            div
+                img(src="../../../assets/images/youtube-music-icon.png")
+                x(data-localise="__MSG_ytmusic__") YoutubeMusic
+            input#youtubeMusic(type="checkbox")
+        div
+            div
+                img(src="../../../assets/images/twitter-icon.png")
+                x(data-localise="__MSG_twitter__") Twitter
+            input#twitter(type="checkbox")
+
+        div
+            div 
+                img(src="../../../assets/images/instagram-icon.png")
+                x(data-localise="__MSG_instagram__") Instagram
+            input#instagram(type="checkbox")
+
+        div 
+            div 
+                img(src="../../../assets/images/tiktok-icon.png")
+                x(data-localise="__MSG_tiktok__") TikTok
+            input#tikTok(type="checkbox")
+
+        div 
+            div 
+                img(src="../../../assets/images/imgur-icon.png")
+                x(data-localise="__MSG_imgur__") Imgur
+            input#imgur(type="checkbox")
+
+        div 
+            div 
+                img(src="../../../assets/images/reddit-icon.png")
+                x(data-localise="__MSG_reddit__") Reddit
+            input#reddit(type="checkbox")
+
+        div 
+            div 
+                svg(xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor")
+                    path(d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z")
+                x(data-localise="__MSG_search__") Search
+            input#search(type="checkbox")
+
+        div 
+            div 
+                svg(xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor")
+                    path(d="M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z")
+                x(data-localise="__MSG_translate__") Translate
+            input#translate(type="checkbox")
+
+        div 
+            div 
+                svg(xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor")
+                    path(d="M20.5 3l-.16.03L15 5.1 9 3 3.36 4.9c-.21.07-.36.25-.36.48V20.5c0 .28.22.5.5.5l.16-.03L9 18.9l6 2.1 5.64-1.9c.21-.07.36-.25.36-.48V3.5c0-.28-.22-.5-.5-.5zM10 5.47l4 1.4v11.66l-4-1.4V5.47zm-5 .99l3-1.01v11.7l-3 1.16V6.46zm14 11.08l-3 1.01V6.86l3-1.16v11.84z")
+                x(data-localise="__MSG_maps__") Maps
+            input#maps(type="checkbox")
+
+        div 
+            div 
+                img(src="../../../assets/images/wikipedia-icon.svg")
+                x(data-localise="__MSG_wikipedia__") Wikipedia
+            input#wikipedia(type="checkbox")
+
+        div 
+            div 
+                svg(xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1770 1000" fill="currentColor")
+                    circle(cx="500" cy="500" r="500")
+                    ellipse(ry="475" rx="250" cy="501" cx="1296")
+                    ellipse(cx="1682" cy="502" rx="88" ry="424")
+                x(data-localise="__MSG_medium__") Medium
+            input#medium(type="checkbox")
+
+        div 
+            div 
+                img(src="../../../assets/images/peertube-icon.svg")
+                x(data-localise="__MSG_peertube__") PeerTube
+            input#peertube(type="checkbox")
+
+        div 
+            div 
+                img(src="../../../assets/images/lbry-icon.png")
+                x(data-localise="__MSG_lbry__") LBRY/Odysee
+            input#lbry(type="checkbox")
+
+        div 
+            div 
+                svg(xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor")
+                    path(d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z")
+                x(data-localise="__MSG_sendFiles__") Send Files
+            input#sendTargets(type="checkbox")
+
+
+    script(type="module" src="./widgets/general.js")
\ No newline at end of file
diff --git a/src/pages/options/widgets/imgur.js b/src/pages/options/widgets/imgur.js
new file mode 100644
index 00000000..036f33ed
--- /dev/null
+++ b/src/pages/options/widgets/imgur.js
@@ -0,0 +1,52 @@
+import imgurHelper from "../../../assets/javascripts/imgur.js";
+import utils from "../../../assets/javascripts/utils.js";
+
+let disableImgurElement = document.getElementById("disable-imgur");
+let protocolElement = document.getElementById("protocol")
+
+document.addEventListener("change", async () => {
+    await browser.storage.local.set({
+        disableImgur: !disableImgurElement.checked,
+        imgurProtocol: protocolElement.value,
+    });
+    changeProtocolSettings(protocolElement.value);
+})
+
+function changeProtocolSettings(protocol) {
+    let normalDiv = document.getElementsByClassName("normal")[0];
+    let torDiv = document.getElementsByClassName("tor")[0];
+    let i2pDiv = document.getElementsByClassName("i2p")[0];
+    if (protocol == 'normal') {
+        normalDiv.style.display = 'block';
+        torDiv.style.display = 'none';
+        i2pDiv.style.display = 'none';
+    }
+    else if (protocol == 'tor') {
+        normalDiv.style.display = 'none';
+        torDiv.style.display = 'block';
+        i2pDiv.style.display = 'none';
+    }
+    else if (protocol == 'i2p') {
+        normalDiv.style.display = 'none';
+        torDiv.style.display = 'none';
+        i2pDiv.style.display = 'block';
+    }
+}
+
+browser.storage.local.get(
+    [
+        "disableImgur",
+        "imgurProtocol",
+    ],
+    r => {
+        disableImgurElement.checked = !r.disableImgur;
+        protocolElement.value = r.imgurProtocol;
+        changeProtocolSettings(r.imgurProtocol);
+    }
+);
+
+utils.processDefaultCustomInstances('imgur', 'rimgo', 'normal', document);
+utils.processDefaultCustomInstances('imgur', 'rimgo', 'tor', document);
+utils.processDefaultCustomInstances('imgur', 'rimgo', 'i2p', document);
+
+utils.latency('imgur', 'rimgo', document, location)
\ No newline at end of file
diff --git a/src/pages/options/widgets/imgur.pug b/src/pages/options/widgets/imgur.pug
new file mode 100644
index 00000000..45104cd3
--- /dev/null
+++ b/src/pages/options/widgets/imgur.pug
@@ -0,0 +1,32 @@
+section#imgur_page.option-block
+    .some-block.option-block
+        h1(data-localise="__MSG_imgur__") Imgur
+    hr
+
+    .some-block.option-block
+        h4(data-localise="__MSG_enable__") Enable
+        input#disable-imgur(type="checkbox")
+
+    .some-block.option-block
+        h4(data-localise="__MSG_protocol__") Protocol
+        select#protocol
+            option(value="normal" data-localise="__MSG_normal__") Normal
+            option(value="tor" data-localise="__MSG_tor__") Tor
+            option(value="i2p" data-localise="__MSG_i2p__") I2P
+
+    #rimgo
+        hr
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://rimgo.com')
+            include ../../widgets/latency.pug
+            +latency()
+        .tor
+            include ../../widgets/instances.pug
+            +instances('https://rimgo.onion')
+
+        .i2p
+            include ../../widgets/instances.pug
+            +instances('https://rimgo.onion')
+
+    script(type="module" src="./widgets/imgur.js")
\ No newline at end of file
diff --git a/src/pages/options/widgets/instagram.js b/src/pages/options/widgets/instagram.js
new file mode 100644
index 00000000..f04fc8c5
--- /dev/null
+++ b/src/pages/options/widgets/instagram.js
@@ -0,0 +1,42 @@
+import instagramHelper from "../../../assets/javascripts/instagram.js";
+import utils from "../../../assets/javascripts/utils.js";
+
+const disable = document.getElementById("disable-bibliogram");
+const protocol = document.getElementById("protocol");
+
+document.addEventListener("change", async () => {
+    await browser.storage.local.set({
+        disableInstagram: disable.checked,
+        instagramProtocol: protocol.value,
+    })
+    changeProtocolSettings();
+})
+
+function changeProtocolSettings() {
+    let normalDiv = document.getElementsByClassName("normal")[0];
+    let torDiv = document.getElementsByClassName("tor")[0];
+    if (protocol.value == 'normal') {
+        normalDiv.style.display = 'block';
+        torDiv.style.display = 'none';
+    }
+    else if (protocol.value == 'tor') {
+        normalDiv.style.display = 'none';
+        torDiv.style.display = 'block';
+    }
+}
+
+browser.storage.local.get(
+    [
+        "disableInstagram",
+        "instagramProtocol"
+    ],
+    r => {
+        disable.checked = !r.disableInstagram;
+        protocol.value = r.instagramProtocol;
+        changeProtocolSettings();
+    })
+
+utils.processDefaultCustomInstances('instagram', 'bibliogram', 'normal', document);
+utils.processDefaultCustomInstances('instagram', 'bibliogram', 'tor', document);
+
+utils.latency('instagram', 'bibliogram', document, location)
\ No newline at end of file
diff --git a/src/pages/options/widgets/instagram.pug b/src/pages/options/widgets/instagram.pug
new file mode 100644
index 00000000..e5698b41
--- /dev/null
+++ b/src/pages/options/widgets/instagram.pug
@@ -0,0 +1,27 @@
+section#instagram_page.option-block
+    .some-block.option-block
+        h1(data-localise="__MSG_instagram__") Instagram
+    hr
+
+    .some-block.option-block
+        h4(data-localise="__MSG_enable__") Enable
+        input#disable-bibliogram(type="checkbox")
+
+    .some-block.option-block
+        h4(data-localise="__MSG_protocol__") Protocol
+        select#protocol
+            option(value="normal" data-localise="__MSG_normal__") Normal
+            option(value="tor" data-localise="__MSG_tor__") Tor
+
+    #bibliogram
+        hr
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://bibliogram.com')
+            include ../../widgets/latency.pug
+            +latency()
+        .tor
+            include ../../widgets/instances.pug
+            +instances('https://bibliogram.onion')
+
+    script(type="module" src="./widgets/instagram.js")
\ No newline at end of file
diff --git a/src/pages/options/widgets/lbry.js b/src/pages/options/widgets/lbry.js
new file mode 100644
index 00000000..2aac362f
--- /dev/null
+++ b/src/pages/options/widgets/lbry.js
@@ -0,0 +1,43 @@
+import lbryHelper from "../../../assets/javascripts/lbry.js";
+import utils from "../../../assets/javascripts/utils.js";
+
+let disable = document.getElementById("disable-lbry");
+let protocol = document.getElementById("protocol")
+
+document.addEventListener("change", async () => {
+    await browser.storage.local.set({
+        disableLbryTargets: !lbryHelper.checked,
+        lbryTargetsProtocol: protocol.value,
+    });
+    changeProtocolSettings()
+})
+
+function changeProtocolSettings() {
+    let normalDiv = document.getElementsByClassName("normal")[0];
+    let torDiv = document.getElementsByClassName("tor")[0];
+    if (protocol.value == 'normal') {
+        normalDiv.style.display = 'block';
+        torDiv.style.display = 'none';
+    }
+    else if (protocol.value == 'tor') {
+        normalDiv.style.display = 'none';
+        torDiv.style.display = 'block';
+    }
+}
+
+browser.storage.local.get(
+    [
+        "disableLbryTargets",
+        "lbryTargetsProtocol"
+    ],
+    r => {
+        disable.checked = !r.disableLbryTargets;
+        protocol.value = r.lbryTargetsProtocol;
+        changeProtocolSettings();
+    }
+)
+
+utils.processDefaultCustomInstances('lbryTargets', 'librarian', 'normal', document);
+utils.processDefaultCustomInstances('lbryTargets', 'librarian', 'tor', document);
+
+utils.latency('lbryTargets', 'librarian', document, location)
\ No newline at end of file
diff --git a/src/pages/options/widgets/lbry.pug b/src/pages/options/widgets/lbry.pug
new file mode 100644
index 00000000..21c4f497
--- /dev/null
+++ b/src/pages/options/widgets/lbry.pug
@@ -0,0 +1,26 @@
+section#lbry_page.option-block
+    .some-block.option-block
+        h1(data-localise="__MSG_lbry__") LBRY/Odysee
+    hr
+    .some-block.option-block
+        h4(data-localise="__MSG_enable__") Enable
+        input#disable-lbry(type="checkbox")
+
+    .some-block.option-block
+        h4(data-localise="__MSG_protocol__") Protocol
+        select#protocol
+            option(value="normal" data-localise="__MSG_normal__") Normal
+            option(value="tor" data-localise="__MSG_tor__") Tor
+
+    #librarian
+        hr
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://librarian.com')
+            include ../../widgets/latency.pug
+            +latency()
+        .tor
+            include ../../widgets/instances.pug
+            +instances('https://librarian.onion')
+
+    script(type="module" src="./widgets/lbry.js")
\ No newline at end of file
diff --git a/src/pages/options/widgets/maps.js b/src/pages/options/widgets/maps.js
new file mode 100644
index 00000000..ddfa8345
--- /dev/null
+++ b/src/pages/options/widgets/maps.js
@@ -0,0 +1,32 @@
+import mapsHelper from "../../../assets/javascripts/maps.js";
+import utils from "../../../assets/javascripts/utils.js";
+
+const disable = document.getElementById("disable-osm");
+const frontend = document.getElementById("maps-frontend");
+
+document.addEventListener("change", async () => {
+    await browser.storage.local.set({
+        disableMaps: !disable.checked,
+        mapsFrontend: frontend.value,
+    })
+    changeFrontendsSettings();
+})
+
+const facilDiv = document.getElementById("facil")
+function changeFrontendsSettings() {
+    if (frontend.value == 'facil') facilDiv.style.display = 'block';
+    else if (frontend.value == 'osm') facilDiv.style.display = 'none';
+}
+
+browser.storage.local.get(
+    [
+        "disableMaps",
+        "mapsFrontend",
+    ],
+    r => {
+        disable.checked = !r.disableMaps;
+        frontend.value = r.mapsFrontend;
+        changeFrontendsSettings();
+    }
+)
+utils.processDefaultCustomInstances('maps', 'facil', 'normal', document);
\ No newline at end of file
diff --git a/src/pages/options/widgets/maps.pug b/src/pages/options/widgets/maps.pug
new file mode 100644
index 00000000..b36c3521
--- /dev/null
+++ b/src/pages/options/widgets/maps.pug
@@ -0,0 +1,23 @@
+section#maps_page.option-block
+    .some-block.option-block
+        h1(data-localise="__MSG_maps__") Maps
+    hr
+    .some-block.option-block
+        h4(data-localise="__MSG_enable__") Enable
+        input#disable-osm(type="checkbox")
+
+    .some-block.option-block
+        h4(data-localise="__MSG_frontend__") Frontend
+        select#maps-frontend
+            option(value="osm") OpenStreetMap
+            option(value="facil") Facil Map
+
+    #facil
+        hr
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://facilmap.com')
+            include ../../widgets/latency.pug
+            +latency()
+
+    script(type="module" src="./widgets/maps.js")
\ No newline at end of file
diff --git a/src/pages/options/widgets/medium.js b/src/pages/options/widgets/medium.js
new file mode 100644
index 00000000..085d6804
--- /dev/null
+++ b/src/pages/options/widgets/medium.js
@@ -0,0 +1,42 @@
+import mediumHelper from "../../../assets/javascripts/medium.js";
+import utils from "../../../assets/javascripts/utils.js";
+
+let disable = document.getElementById("disable-medium");
+let protocol = document.getElementById("protocol")
+
+browser.storage.local.get(
+    [
+        "disableMedium",
+        "mediumProtocol"
+    ],
+    r => {
+        disable.checked = !r.disableMedium;
+        protocol.value = r.mediumProtocol;
+        changeProtocolSettings();
+    }
+)
+utils.processDefaultCustomInstances('medium', 'scribe', 'normal', document);
+utils.processDefaultCustomInstances('medium', 'scribe', 'tor', document);
+
+document.addEventListener("change", async () => {
+    await browser.storage.local.set({
+        disableMedium: !disable.checked,
+        mediumProtocol: protocol.value,
+    })
+    changeProtocolSettings();
+})
+
+function changeProtocolSettings() {
+    let normalDiv = document.getElementsByClassName("normal")[0];
+    let torDiv = document.getElementsByClassName("tor")[0];
+    if (protocol.value == 'normal') {
+        normalDiv.style.display = 'block';
+        torDiv.style.display = 'none';
+    }
+    else if (protocol.value == 'tor') {
+        normalDiv.style.display = 'none';
+        torDiv.style.display = 'block';
+    }
+}
+
+utils.latency('medium', 'scribe', document, location)
\ No newline at end of file
diff --git a/src/pages/options/widgets/medium.pug b/src/pages/options/widgets/medium.pug
new file mode 100644
index 00000000..10c18f6d
--- /dev/null
+++ b/src/pages/options/widgets/medium.pug
@@ -0,0 +1,26 @@
+section#medium_page.option-block
+    .some-block.option-block
+        h1(data-localise="__MSG_medium__") Medium
+    hr
+    .some-block.option-block
+        h4(data-localise="__MSG_enable__") Enable
+        input#disable-medium(type="checkbox")
+
+    .some-block.option-block
+        h4(data-localise="__MSG_protocol__") Protocol
+        select#protocol
+            option(value="normal" data-localise="__MSG_normal__") Normal
+            option(value="tor" data-localise="__MSG_tor__") Tor
+
+    #scribe
+        hr
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://scribe.com')
+            include ../../widgets/latency.pug
+            +latency()
+        .tor
+            include ../../widgets/instances.pug
+            +instances('https://scribe.onion')
+
+    script(type="module" src="./widgets/medium.js")
\ No newline at end of file
diff --git a/src/pages/options/widgets/peertube.js b/src/pages/options/widgets/peertube.js
new file mode 100644
index 00000000..f2cede89
--- /dev/null
+++ b/src/pages/options/widgets/peertube.js
@@ -0,0 +1,40 @@
+import peertubeHelper from "../../../assets/javascripts/peertube.js";
+import utils from "../../../assets/javascripts/utils.js";
+
+let disable = document.getElementById("disable-peertube");
+let protocol = document.getElementById("protocol")
+browser.storage.local.get(
+    [
+        "disablePeertubeTargets",
+        "peertubeTargetsProtocol"
+    ],
+    r => {
+        disable.checked = !r.disablePeertubeTargets;
+        protocol.value = r.peertubeTargetsProtocol;
+        changeProtocolSettings();
+    }
+)
+utils.processDefaultCustomInstances('peertube', 'simpleertube', 'normal', document);
+utils.processDefaultCustomInstances('peertube', 'simpleertube', 'tor', document);
+
+document.addEventListener("change", async () => {
+    await browser.storage.local.set({
+        disablePeertubeTargets: !disable.checked,
+        peertubeTargetsProtocol: protocol.value
+    })
+    changeProtocolSettings();
+})
+
+function changeProtocolSettings() {
+    const normalDiv = document.getElementsByClassName("normal")[0];
+    const torDiv = document.getElementsByClassName("tor")[0];
+    if (protocol.value == 'normal') {
+        normalDiv.style.display = 'block';
+        torDiv.style.display = 'none';
+    }
+    else if (protocol.value == 'tor') {
+        normalDiv.style.display = 'none';
+        torDiv.style.display = 'block';
+    }
+}
+utils.latency('peertube', 'simpleertube', document, location)
\ No newline at end of file
diff --git a/src/pages/options/widgets/peertube.pug b/src/pages/options/widgets/peertube.pug
new file mode 100644
index 00000000..496fb2df
--- /dev/null
+++ b/src/pages/options/widgets/peertube.pug
@@ -0,0 +1,26 @@
+section#peertube_page.option-block
+    .some-block.option-block
+        h1(data-localise="__MSG_peertube__") PeerTube
+    hr
+    .some-block.option-block
+        h4(data-localise="__MSG_enable__") Enable
+        input#disable-peertube(type="checkbox")
+
+    .some-block.option-block
+        h4(data-localise="__MSG_protocol__") Protocol
+        select#protocol
+            option(value="normal" data-localise="__MSG_normal__") Normal
+            option(value="tor" data-localise="__MSG_tor__") Tor
+
+    #simpleertube
+        hr
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://simpleertube.com')
+            include ../../widgets/latency.pug
+            +latency()
+        .tor
+            include ../../widgets/instances.pug
+            +instances('https://simpleertube.onion')
+
+    script(type="module" src="./widgets/peertube.js")
\ No newline at end of file
diff --git a/src/pages/options/widgets/reddit.js b/src/pages/options/widgets/reddit.js
new file mode 100644
index 00000000..da4221aa
--- /dev/null
+++ b/src/pages/options/widgets/reddit.js
@@ -0,0 +1,90 @@
+import redditHelper from "../../../assets/javascripts/reddit.js";
+import utils from "../../../assets/javascripts/utils.js";
+
+let libredditDivElement = document.getElementById("libreddit")
+let tedditDivElement = document.getElementById("teddit")
+
+let disableRedditElement = document.getElementById("disable-reddit");
+let frontend = document.getElementById("reddit-frontend");
+let protocol = document.getElementById("protocol")
+
+document.addEventListener("change", () => {
+    browser.storage.local.set({
+        disableReddit: !disableRedditElement.checked,
+        redditProtocol: protocol.value,
+        redditFrontend: frontend.value,
+    });
+    changeFrontendsSettings();
+    changeProtocolSettings();
+})
+
+const libredditForm = libredditDivElement.getElementsByTagName('form')[0];
+const libredditCookies = libredditForm.getElementsByTagName('input')[0];
+libredditForm.addEventListener('submit', async event => {
+    event.preventDefault();
+    const url = new URL(libredditCookies.value);
+    redditHelper.initLibredditCookies(url);
+});
+
+const tedditForm = tedditDivElement.getElementsByTagName('form')[0];
+const tedditCookies = tedditForm.getElementsByTagName('input')[0];
+tedditForm.addEventListener('submit', async event => {
+    event.preventDefault();
+    const url = new URL(tedditCookies.value);
+    redditHelper.initTedditCookies(url);
+});
+
+function changeProtocolSettings() {
+    let normalLibredditDiv = libredditDivElement.getElementsByClassName("normal")[0];
+    let torLibredditDiv = libredditDivElement.getElementsByClassName("tor")[0];
+
+    let normalTedditDiv = tedditDivElement.getElementsByClassName("normal")[0];
+    let torTedditDiv = tedditDivElement.getElementsByClassName("tor")[0];
+    if (protocol.value == 'normal') {
+        normalLibredditDiv.style.display = 'block';
+        normalTedditDiv.style.display = 'block';
+        torTedditDiv.style.display = 'none';
+        torLibredditDiv.style.display = 'none';
+    }
+    else if (protocol.value == 'tor') {
+        normalLibredditDiv.style.display = 'none';
+        normalTedditDiv.style.display = 'none';
+        torTedditDiv.style.display = 'block';
+        torLibredditDiv.style.display = 'block';
+    }
+}
+function changeFrontendsSettings() {
+    if (frontend.value == 'libreddit') {
+        libredditDivElement.style.display = 'block';
+        tedditDivElement.style.display = 'none';
+    }
+    else if (frontend.value == 'teddit') {
+        libredditDivElement.style.display = 'none';
+        tedditDivElement.style.display = 'block';
+    }
+}
+
+browser.storage.local.get(
+    [
+        "disableReddit",
+        "redditProtocol",
+        "redditFrontend",
+
+        "enableLibredditCustomSettings",
+    ],
+    r => {
+        disableRedditElement.checked = !r.disableReddit
+        protocol.value = r.redditProtocol
+        frontend.value = r.redditFrontend
+        changeFrontendsSettings();
+        changeProtocolSettings();
+    }
+)
+
+utils.processDefaultCustomInstances('reddit', 'libreddit', 'normal', document);
+utils.processDefaultCustomInstances('reddit', 'libreddit', 'tor', document);
+utils.processDefaultCustomInstances('reddit', 'teddit', 'normal', document);
+utils.processDefaultCustomInstances('reddit', 'teddit', 'tor', document);
+
+utils.latency('reddit', 'libreddit', document, location, true)
+utils.latency('reddit', 'teddit', document, location, true)
\ No newline at end of file
diff --git a/src/pages/options/widgets/reddit.pug b/src/pages/options/widgets/reddit.pug
new file mode 100644
index 00000000..ae72b31f
--- /dev/null
+++ b/src/pages/options/widgets/reddit.pug
@@ -0,0 +1,42 @@
+section#reddit_page.option-block
+    .some-block.option-block
+        h1(data-localise="__MSG_reddit__") Reddit
+    hr
+    .some-block.option-block
+        h4(data-localise="__MSG_enable__") Enable
+        input#disable-reddit(type="checkbox")
+
+    .some-block.option-block
+        h4#frontend(data-localise="__MSG_frontend__") Frontend
+        select#reddit-frontend
+            option(value="libreddit") Libreddit
+            option(value="teddit") Teddit
+
+    .some-block.option-block
+        h4(data-localise="__MSG_protocol__") Protocol
+        select#protocol
+            option(value="normal" data-localise="__MSG_normal__") Normal
+            option(value="tor" data-localise="__MSG_tor__") Tor
+
+    #libreddit
+        hr
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://libreddit.com')
+            include ../../widgets/latency.pug
+            +latency('libreddit')
+        .tor
+            include ../../widgets/instances.pug
+            +instances('https://libreddit.onion')
+
+    #teddit
+        hr
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://teddit.com')
+            +latency('teddit')
+        .tor
+            include ../../widgets/instances.pug
+            +instances('https://teddit.onion')
+
+    script(type="module" src="./widgets/reddit.js")
\ No newline at end of file
diff --git a/src/pages/options/widgets/search.js b/src/pages/options/widgets/search.js
new file mode 100644
index 00000000..2506279a
--- /dev/null
+++ b/src/pages/options/widgets/search.js
@@ -0,0 +1,142 @@
+import searchHelper from "../../../assets/javascripts/search.js";
+import utils from "../../../assets/javascripts/utils.js";
+
+let searxDiv = document.getElementById("searx");
+let searxngDiv = document.getElementById("searxng");
+let whoogleDiv = document.getElementById("whoogle");
+
+let disable = document.getElementById("disable-search");
+let frontend = document.getElementById("search-frontend");
+let protocol = document.getElementById("protocol")
+
+const searxngForm = searxngDiv.getElementsByTagName('form')[0];
+const searxngCookies = searxngForm.getElementsByTagName('input')[0];
+searxngForm.addEventListener('submit', async event => {
+  event.preventDefault();
+  const url = new URL(searxngCookies.value);
+  searchHelper.initSearxngCookies(url);
+});
+
+const searxForm = searxDiv.getElementsByTagName('form')[0];
+const searxCookies = searxForm.getElementsByTagName('input')[0];
+searxForm.addEventListener('submit', async event => {
+  event.preventDefault();
+  const url = new URL(searxCookies.value);
+  searchHelper.initSearxCookies(url);
+});
+
+browser.storage.local.get(
+  [
+    "disableSearch",
+    "searchFrontend",
+    "searchProtocol",
+  ],
+  r => {
+    disable.checked = !r.disableSearch;
+    frontend.value = r.searchFrontend;
+    protocol.value = r.searchProtocol;
+
+    changeFrontendsSettings();
+    changeProtocolSettings();
+  }
+);
+
+document.addEventListener("change", async () => {
+  await browser.storage.local.set({
+    disableSearch: !disable.checked,
+    searchFrontend: frontend.value,
+    searchProtocol: protocol.value,
+  });
+  changeFrontendsSettings(frontend.value);
+  changeProtocolSettings(protocol.value);
+})
+
+function changeFrontendsSettings() {
+  let SearxWhoogleElement = document.getElementById("searx-whoogle");
+  if (frontend.value == 'searx') {
+    searxDiv.style.display = 'block';
+    searxngDiv.style.display = 'none';
+    whoogleDiv.style.display = 'none';
+    SearxWhoogleElement.style.display = 'block';
+  }
+  else if (frontend.value == 'searxng') {
+    searxDiv.style.display = 'none';
+    searxngDiv.style.display = 'block';
+    whoogleDiv.style.display = 'none';
+    SearxWhoogleElement.style.display = 'block';
+  }
+  else if (frontend.value == 'whoogle') {
+    searxDiv.style.display = 'none';
+    searxngDiv.style.display = 'none';
+    whoogleDiv.style.display = 'block';
+    SearxWhoogleElement.style.display = 'block';
+  }
+}
+
+function changeProtocolSettings() {
+  let normalsearxDiv = searxDiv.getElementsByClassName("normal")[0];
+  let torsearxDiv = searxDiv.getElementsByClassName("tor")[0];
+  let i2psearxDiv = searxDiv.getElementsByClassName("i2p")[0];
+
+  let normalsearxngDiv = searxngDiv.getElementsByClassName("normal")[0];
+  let torsearxngDiv = searxngDiv.getElementsByClassName("tor")[0];
+  let i2psearxngDiv = searxngDiv.getElementsByClassName("i2p")[0];
+
+  let normalwhoogleDiv = whoogleDiv.getElementsByClassName("normal")[0];
+  let torwhoogleDiv = whoogleDiv.getElementsByClassName("tor")[0];
+  let i2pwhoogleDiv = whoogleDiv.getElementsByClassName("i2p")[0];
+
+  if (protocol.value == 'normal') {
+    normalsearxDiv.style.display = 'block';
+    normalsearxngDiv.style.display = 'block';
+    normalwhoogleDiv.style.display = 'block';
+
+    torsearxDiv.style.display = 'none';
+    torsearxngDiv.style.display = 'none';
+    torwhoogleDiv.style.display = 'none';
+
+    i2psearxDiv.style.display = 'none';
+    i2psearxngDiv.style.display = 'none';
+    i2pwhoogleDiv.style.display = 'none';
+  }
+  else if (protocol.value == 'tor') {
+    normalsearxDiv.style.display = 'none';
+    normalsearxngDiv.style.display = 'none';
+    normalwhoogleDiv.style.display = 'none';
+
+    torsearxDiv.style.display = 'block';
+    torsearxngDiv.style.display = 'block';
+    torwhoogleDiv.style.display = 'block';
+
+    i2psearxDiv.style.display = 'none';
+    i2psearxngDiv.style.display = 'none';
+    i2pwhoogleDiv.style.display = 'none';
+  }
+  else if (protocol.value == 'i2p') {
+    normalsearxDiv.style.display = 'none';
+    normalsearxngDiv.style.display = 'none';
+    normalwhoogleDiv.style.display = 'none';
+
+    torsearxDiv.style.display = 'none';
+    torsearxngDiv.style.display = 'none';
+    torwhoogleDiv.style.display = 'none';
+
+    i2psearxDiv.style.display = 'block';
+    i2psearxngDiv.style.display = 'block';
+    i2pwhoogleDiv.style.display = 'block';
+  }
+}
+
+utils.processDefaultCustomInstances('search', 'searx', 'normal', document);
+utils.processDefaultCustomInstances('search', 'searx', 'tor', document);
+utils.processDefaultCustomInstances('search', 'searx', 'i2p', document);
+utils.processDefaultCustomInstances('search', 'searxng', 'normal', document);
+utils.processDefaultCustomInstances('search', 'searxng', 'tor', document);
+utils.processDefaultCustomInstances('search', 'searxng', 'i2p', document);
+utils.processDefaultCustomInstances('search', 'whoogle', 'normal', document);
+utils.processDefaultCustomInstances('search', 'whoogle', 'tor', document);
+utils.processDefaultCustomInstances('search', 'whoogle', 'i2p', document);
+
+utils.latency('search', 'searx', document, location, true)
+utils.latency('search', 'searxng', document, location, true)
+utils.latency('search', 'whoogle', document, location, true)
diff --git a/src/pages/options/widgets/search.pug b/src/pages/options/widgets/search.pug
new file mode 100644
index 00000000..feea4b0d
--- /dev/null
+++ b/src/pages/options/widgets/search.pug
@@ -0,0 +1,69 @@
+
+section#search_page.option-block
+    .some-block.option-block
+        h1(data-localise="__MSG_search__") Search
+    hr
+    .some-block.option-block
+        h4(data-localise="__MSG_enable__") Enable
+        input#disable-search(type="checkbox")
+
+    .some-block.option-block
+        h4(data-localise="__MSG_frontend__") Frontend
+        select#search-frontend
+            option(value="searxng") SearXNG
+            option(value="searx") SearX
+            option(value="whoogle") Whoogle
+
+
+    #searx-whoogle
+        .some-block.option-block
+            h4(data-localise="__MSG_protocol__") Protocol
+            select#protocol
+                option(value="normal" data-localise="__MSG_normal__") Normal
+                option(value="tor" data-localise="__MSG_tor__") Tor
+                option(value="i2p" data-localise="__MSG_i2p__") I2P
+
+    .some-block
+        h4(data-localise="__MSG_searchNote__") Note: To use Search to its full potential, make LibRedirect as the Default Search Engine
+
+    #searx
+        hr
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://searx.com')
+            include ../../widgets/latency.pug
+            +latency('searx')
+        .tor
+            include ../../widgets/instances.pug
+            +instances('https://searx.onion')
+        .i2p
+            include ../../widgets/instances.pug
+            +instances('https://searx.i2p')
+
+    #searxng
+        hr
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://searxng.com')
+            +latency('searxng')
+        .tor
+            include ../../widgets/instances.pug
+            +instances('https://searxng.onion')
+        .i2p
+            include ../../widgets/instances.pug
+            +instances('https://searxng.i2p')
+
+    #whoogle
+        hr
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://whoogle.com')
+            +latency('whoogle')
+        .tor
+            include ../../widgets/instances.pug
+            +instances('https://whoogle.onion')
+        .i2p
+            include ../../widgets/instances.pug
+            +instances('https://whoogle.i2p')
+
+    script(type="module" src="./widgets/search.js")
\ No newline at end of file
diff --git a/src/pages/options/widgets/sendTargets.js b/src/pages/options/widgets/sendTargets.js
new file mode 100644
index 00000000..37e2588e
--- /dev/null
+++ b/src/pages/options/widgets/sendTargets.js
@@ -0,0 +1,43 @@
+import sendTargetsHelper from "../../../assets/javascripts/sendTargets.js";
+import utils from "../../../assets/javascripts/utils.js";
+
+let disable = document.getElementById("disable-sendTargets");
+let protocol = document.getElementById("protocol")
+
+browser.storage.local.get(
+    [
+        "disableSendTarget",
+        "sendTargetsProtocol",
+    ],
+    r => {
+        disable.checked = !r.disableSendTarget;
+        protocol.value = r.sendTargetsProtocol;
+        changeProtocolSettings();
+    }
+)
+
+document.addEventListener("change", async () => {
+    await browser.storage.local.set({
+        disableSendTarget: !disable.checked,
+        sendTargetsProtocol: protocol.value,
+    })
+    changeProtocolSettings();
+})
+
+function changeProtocolSettings() {
+    let normalDiv = document.getElementsByClassName("normal")[0];
+    let torDiv = document.getElementsByClassName("tor")[0];
+    if (protocol.value == 'normal') {
+        normalDiv.style.display = 'block';
+        torDiv.style.display = 'none';
+    }
+    else if (protocol.value == 'tor') {
+        normalDiv.style.display = 'none';
+        torDiv.style.display = 'block';
+    }
+}
+
+utils.processDefaultCustomInstances('sendTargets', 'send', 'normal', document);
+utils.processDefaultCustomInstances('sendTargets', 'send', 'tor', document);
+
+utils.latency('sendTargets', 'send', document, location)
\ No newline at end of file
diff --git a/src/pages/options/widgets/sendTargets.pug b/src/pages/options/widgets/sendTargets.pug
new file mode 100644
index 00000000..c4a933d1
--- /dev/null
+++ b/src/pages/options/widgets/sendTargets.pug
@@ -0,0 +1,26 @@
+section#sendTargets_page.option-block
+    .some-block.option-block
+        h1(data-localise="__MSG_sendFiles__") Send Files
+    hr
+    .some-block.option-block
+        h4(data-localise="__MSG_enable__") Enable
+        input#disable-sendTargets(type="checkbox")
+
+    .some-block.option-block
+        h4(data-localise="__MSG_protocol__") Protocol
+        select#protocol
+            option(value="normal" data-localise="__MSG_normal__") Normal
+            option(value="tor" data-localise="__MSG_tor__") Tor
+
+    #send
+        hr
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://send.com')
+            include ../../widgets/latency.pug
+            +latency()
+        .tor
+            include ../../widgets/instances.pug
+            +instances('https://send.onion')
+
+    script(type="module" src="./widgets/sendTargets.js")
\ No newline at end of file
diff --git a/src/pages/options/widgets/tiktok.js b/src/pages/options/widgets/tiktok.js
new file mode 100644
index 00000000..6b5702e1
--- /dev/null
+++ b/src/pages/options/widgets/tiktok.js
@@ -0,0 +1,53 @@
+import tiktokHelper from "../../../assets/javascripts/tiktok.js";
+import utils from "../../../assets/javascripts/utils.js";
+
+let disable = document.getElementById("disable-tiktok");
+let protocol = document.getElementById("protocol")
+
+document.addEventListener("change", () => {
+    browser.storage.local.set({
+        disableTiktok: !disable.checked,
+        tiktokProtocol: protocol.value,
+    });
+    changeProtocolSettings();
+})
+
+browser.storage.local.get(
+    [
+        "disableTiktok",
+        "tiktokProtocol",
+    ],
+    r => {
+        disable.checked = !r.disableTiktok;
+        protocol.value = r.tiktokProtocol;
+        changeProtocolSettings();
+        let normalDiv = document.getElementsByClassName("normal")[0];
+        let torDiv = document.getElementsByClassName("tor")[0];
+        if (r.tiktokProtocol == 'normal') {
+            normalDiv.style.display = 'block';
+            torDiv.style.display = 'none';
+        }
+        else if (r.tiktokProtocol == 'tor') {
+            normalDiv.style.display = 'none';
+            torDiv.style.display = 'block';
+        }
+    }
+)
+
+function changeProtocolSettings() {
+    let normalDiv = document.getElementsByClassName("normal")[0];
+    let torDiv = document.getElementsByClassName("tor")[0];
+    if (protocol.value == 'normal') {
+        normalDiv.style.display = 'block';
+        torDiv.style.display = 'none';
+    }
+    else if (protocol.value == 'tor') {
+        normalDiv.style.display = 'none';
+        torDiv.style.display = 'block';
+    }
+}
+
+utils.processDefaultCustomInstances('tiktok', 'proxiTok', 'normal', document);
+utils.processDefaultCustomInstances('tiktok', 'proxiTok', 'tor', document);
+
+utils.latency('tiktok', 'proxiTok', document, location)
\ No newline at end of file
diff --git a/src/pages/options/widgets/tiktok.pug b/src/pages/options/widgets/tiktok.pug
new file mode 100644
index 00000000..ec55671c
--- /dev/null
+++ b/src/pages/options/widgets/tiktok.pug
@@ -0,0 +1,26 @@
+section#tiktok_page.option-block
+    .some-block.option-block
+        h1(data-localise="__MSG_tiktok__") TikTok
+    hr
+    .some-block.option-block
+        h4(data-localise="__MSG_enable__") Enable
+        input#disable-tiktok(type="checkbox")
+
+    .some-block.option-block
+        h4(data-localise="__MSG_protocol__") Protocol
+        select#protocol
+            option(value="normal" data-localise="__MSG_normal__") Normal
+            option(value="tor" data-localise="__MSG_tor__") Tor
+    
+    #proxiTok
+        hr
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://proxitok.com')
+            include ../../widgets/latency.pug
+            +latency()
+        .tor
+            include ../../widgets/instances.pug
+            +instances('https://proxitok.onion')
+
+    script(type="module" src="./widgets/tiktok.js")
diff --git a/src/pages/options/widgets/translate.js b/src/pages/options/widgets/translate.js
new file mode 100644
index 00000000..3e1990f4
--- /dev/null
+++ b/src/pages/options/widgets/translate.js
@@ -0,0 +1,75 @@
+import translateHelper from "../../../assets/javascripts/translate/translate.js";
+import utils from "../../../assets/javascripts/utils.js";
+
+let disable = document.getElementById("disable-simplyTranslate");
+let simplyTranslateDiv = document.getElementById("simplyTranslate");
+let lingvaDiv = document.getElementById("lingva");
+let frontend = document.getElementById("translate-frontend");
+let protocol = document.getElementById("protocol");
+
+
+function changeFrontendsSettings() {
+    if (frontend.value == 'simplyTranslate') {
+        simplyTranslateDiv.style.display = 'block';
+        lingvaDiv.style.display = 'none';
+    }
+    else if (frontend.value == 'lingva') {
+        simplyTranslateDiv.style.display = 'none';
+        lingvaDiv.style.display = 'block';
+    }
+}
+
+function changeProtocolSettings() {
+    let normalSimplyTranslateDiv = document.getElementById("simplyTranslate").getElementsByClassName("normal")[0];
+    let torSimplyTranslateDiv = document.getElementById("simplyTranslate").getElementsByClassName("tor")[0];
+
+    let normalLingvaDiv = document.getElementById("lingva").getElementsByClassName("normal")[0];
+    let torLingvaDiv = document.getElementById("lingva").getElementsByClassName("tor")[0];
+
+    if (protocol.value == 'normal') {
+        normalSimplyTranslateDiv.style.display = 'block';
+        normalLingvaDiv.style.display = 'block';
+        torLingvaDiv.style.display = 'none';
+        torSimplyTranslateDiv.style.display = 'none';
+    }
+    else if (protocol.value == 'tor') {
+        normalSimplyTranslateDiv.style.display = 'none';
+        normalLingvaDiv.style.display = 'none';
+        torLingvaDiv.style.display = 'block';
+        torSimplyTranslateDiv.style.display = 'block';
+    }
+}
+
+browser.storage.local.get(
+    [
+        "translateDisable",
+        "translateFrontend",
+        "translateProtocol",
+    ],
+    r => {
+        disable.checked = !r.translateDisable;
+        frontend.value = r.translateFrontend;
+        protocol.value = r.translateProtocol;
+        changeFrontendsSettings();
+        changeProtocolSettings();
+    }
+);
+
+document.addEventListener("change", () => {
+    browser.storage.local.set({
+        translateDisable: !disable.checked,
+        translateFrontend: frontend.value,
+        translateProtocol: protocol.value,
+    })
+    changeProtocolSettings();
+    changeFrontendsSettings();
+})
+
+
+utils.processDefaultCustomInstances('translate', 'simplyTranslate', 'normal', document)
+utils.processDefaultCustomInstances('translate', 'simplyTranslate', 'tor', document);
+utils.processDefaultCustomInstances('translate', 'lingva', 'normal', document);
+utils.processDefaultCustomInstances('translate', 'lingva', 'tor', document);
+
+utils.latency('translate', 'simplyTranslate', document, location, true)
+utils.latency('translate', 'lingva', document, location, true)
\ No newline at end of file
diff --git a/src/pages/options/widgets/translate.pug b/src/pages/options/widgets/translate.pug
new file mode 100644
index 00000000..a97a4245
--- /dev/null
+++ b/src/pages/options/widgets/translate.pug
@@ -0,0 +1,40 @@
+section#translate_page.option-block
+    .some-block.option-block
+        h1(data-localise="__MSG_translate__") Translate
+    hr
+    .some-block.option-block
+        h4(data-localise="__MSG_enable__") Enable
+        input#disable-simplyTranslate(type="checkbox")
+
+    .some-block.option-block
+        h4(data-localise="__MSG_frontend__") Frontend
+        select#translate-frontend
+            option(value="simplyTranslate") SimplyTranslate
+            option(value="lingva") Lingva
+
+    .some-block.option-block
+        h4(data-localise="__MSG_protocol__") Protocol
+        select#protocol
+            option(value="normal" data-localise="__MSG_normal__") Normal
+            option(value="tor" data-localise="__MSG_tor__") Tor
+
+    hr
+    #simplyTranslate
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://simplytranslate.org')
+            include ../../widgets/latency.pug
+            +latency('simplyTranslate')
+        .tor
+            include ../../widgets/instances.pug
+            +instances('http://hxecvvetgrznmprg.onion')
+    #lingva
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://lingvatranslate.com')
+            +latency('lingva')
+        .tor
+            include ../../widgets/instances.pug
+            +instances('http://tyzxppdeoojdnaux.onion')
+
+    script(type="module" src="./widgets/translate.js")
diff --git a/src/pages/options/widgets/twitter.js b/src/pages/options/widgets/twitter.js
new file mode 100644
index 00000000..266fd027
--- /dev/null
+++ b/src/pages/options/widgets/twitter.js
@@ -0,0 +1,53 @@
+import twitterHelper from "../../../assets/javascripts/twitter.js";
+import utils from "../../../assets/javascripts/utils.js";
+
+let disable = document.getElementById("disable-nitter");
+let protocol = document.getElementById("protocol");
+
+let nitterDiv = document.getElementById('nitter');
+
+const nitterForm = nitterDiv.getElementsByTagName('form')[0];
+const nitterCookies = nitterForm.getElementsByTagName('input')[0];
+nitterForm.addEventListener('submit', event => {
+  event.preventDefault();
+  const url = new URL(nitterCookies.value);
+  twitterHelper.initNitterCookies(url);
+});
+
+browser.storage.local.get(
+    [
+        "disableTwitter",
+        "twitterProtocol",
+    ],
+    r => {
+        disable.checked = !r.disableTwitter;
+        protocol.value = r.twitterProtocol;
+        changeProtocolSettings();
+    }
+)
+
+document.addEventListener("change", () => {
+    browser.storage.local.set({
+        disableTwitter: !disable.checked,
+        twitterProtocol: protocol.value,
+    });
+    changeProtocolSettings();
+})
+
+function changeProtocolSettings() {
+    let normalDiv = nitterDiv.getElementsByClassName("normal")[0];
+    let torDiv = nitterDiv.getElementsByClassName("tor")[0];
+    if (protocol.value == 'normal') {
+        normalDiv.style.display = 'block';
+        torDiv.style.display = 'none';
+    }
+    else if (protocol.value == 'tor') {
+        normalDiv.style.display = 'none';
+        torDiv.style.display = 'block';
+    }
+}
+
+utils.processDefaultCustomInstances('twitter', 'nitter', 'normal', document);
+utils.processDefaultCustomInstances('twitter', 'nitter', 'tor', document)
+
+utils.latency('twitter', 'nitter', document, location)
\ No newline at end of file
diff --git a/src/pages/options/widgets/twitter.pug b/src/pages/options/widgets/twitter.pug
new file mode 100644
index 00000000..af743dcd
--- /dev/null
+++ b/src/pages/options/widgets/twitter.pug
@@ -0,0 +1,26 @@
+section#twitter_page.option-block
+    .some-block.option-block
+        h1(data-localise="__MSG_twitter__") Twitter
+    hr
+    .some-block.option-block
+        h4(data-localise="__MSG_enable__") Enable
+        input#disable-nitter(type="checkbox")
+
+    .some-block.option-block
+        h4(data-localise="__MSG_protocol__") Protocol
+        select#protocol
+            option(value="normal" data-localise="__MSG_normal__") Normal
+            option(value="tor" data-localise="__MSG_tor__") Tor
+
+    #nitter
+        hr
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://nitter.com')
+            include ../../widgets/latency.pug
+            +latency()
+        .tor
+            include ../../widgets/instances.pug
+            +instances('https://nitter.onion')
+
+    script(type="module" src="./widgets/twitter.js")
diff --git a/src/pages/options/widgets/wikipedia.js b/src/pages/options/widgets/wikipedia.js
new file mode 100644
index 00000000..6e847c8d
--- /dev/null
+++ b/src/pages/options/widgets/wikipedia.js
@@ -0,0 +1,51 @@
+import wikipediaHelper from "../../../assets/javascripts/wikipedia.js";
+import utils from "../../../assets/javascripts/utils.js";
+
+let disableWikipediaElement = document.getElementById("disable-wikipedia");
+let protocolElement = document.getElementById("protocol");
+
+browser.storage.local.get(
+    [
+        "disableWikipedia",
+        "wikipediaProtocol",
+    ],
+    r => {
+        disableWikipediaElement.checked = !r.disableWikipedia;
+        protocolElement.value = r.wikipediaProtocol;
+        changeProtocolSettings(r.wikipediaProtocol);
+    }
+)
+
+document.addEventListener("change", async () => {
+    await browser.storage.local.set({
+        disableWikipedia: !disableWikipediaElement.checked,
+        wikipediaProtocol: protocolElement.value,
+    })
+    changeProtocolSettings(protocolElement.value)
+})
+
+function changeProtocolSettings(protocol) {
+    let normalDiv = document.getElementsByClassName("normal")[0];
+    let torDiv = document.getElementsByClassName("tor")[0];
+    let i2pDiv = document.getElementsByClassName("i2p")[0];
+    if (protocol == 'normal') {
+        normalDiv.style.display = 'block';
+        torDiv.style.display = 'none';
+        i2pDiv.style.display = 'none';
+    }
+    else if (protocol == 'tor') {
+        normalDiv.style.display = 'none';
+        torDiv.style.display = 'block';
+        i2pDiv.style.display = 'none';
+    }
+    else if (protocol == 'i2p') {
+        normalDiv.style.display = 'none';
+        torDiv.style.display = 'none';
+        i2pDiv.style.display = 'block';
+    }
+}
+utils.processDefaultCustomInstances('wikipedia', 'wikiless', 'normal', document);
+utils.processDefaultCustomInstances('wikipedia', 'wikiless', 'tor', document);
+utils.processDefaultCustomInstances('wikipedia', 'wikiless', 'i2p', document);
+
+utils.latency('wikipedia', 'wikiless', document, location)
\ No newline at end of file
diff --git a/src/pages/options/widgets/wikipedia.pug b/src/pages/options/widgets/wikipedia.pug
new file mode 100644
index 00000000..79d1e323
--- /dev/null
+++ b/src/pages/options/widgets/wikipedia.pug
@@ -0,0 +1,32 @@
+section#wikipedia_page.option-block
+    .some-block.option-block
+        h1(data-localise="__MSG_wikipedia__") Wikipedia
+    hr
+    .some-block.option-block
+        h4(data-localise="__MSG_enable__") Enable
+        input#disable-wikipedia(type="checkbox")
+
+    .some-block.option-block
+        h4(data-localise="__MSG_protocol__") Protocol
+        select#protocol
+            option(value="normal" data-localise="__MSG_normal__") Normal
+            option(value="tor" data-localise="__MSG_tor__") Tor
+            option(value="i2p" data-localise="__MSG_i2p__") I2P
+
+    #wikiless
+        hr
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://wikiless.com')
+            include ../../widgets/latency.pug
+            +latency()
+        .tor
+            include ../../widgets/instances.pug
+            +instances('https://wikiless.onion')
+
+        .i2p
+            include ../../widgets/instances.pug
+            +instances('https://wikiless.i2p')
+
+    script(type="module" src="./widgets/wikipedia.js")
+    
\ No newline at end of file
diff --git a/src/pages/options/widgets/youtube.js b/src/pages/options/widgets/youtube.js
new file mode 100644
index 00000000..7826541b
--- /dev/null
+++ b/src/pages/options/widgets/youtube.js
@@ -0,0 +1,161 @@
+import youtubeHelper from "../../../assets/javascripts/youtube/youtube.js";
+import utils from "../../../assets/javascripts/utils.js";
+
+let disableYoutube = document.getElementById("disable-invidious");
+let youtubeFrontend = document.getElementById("youtube-frontend");
+let invidiousDiv = document.getElementById("invidious");
+let pipedDiv = document.getElementById("piped");
+let pipedMaterialDiv = document.getElementById("pipedMaterial");
+let freetubeYatteeDiv = document.getElementById("freetube-yatte");
+let youtubeEmbedFrontend = document.getElementById("youtube-embed-frontend");
+let OnlyEmbeddedVideo = document.getElementById("only-embed");
+let protoco = document.getElementById("protocol");
+
+function changeFrontendsSettings() {
+    let frontend = youtubeFrontend.value;
+
+    if (frontend == 'invidious') {
+        invidiousDiv.style.display = 'block';
+        pipedDiv.style.display = 'none';
+        pipedMaterialDiv.style.display = 'none';
+        freetubeYatteeDiv.style.display = 'none';
+    }
+    else if (frontend == 'piped') {
+        invidiousDiv.style.display = 'none';
+        pipedDiv.style.display = 'block';
+        pipedMaterialDiv.style.display = 'none';
+        freetubeYatteeDiv.style.display = 'none';
+    }
+    else if (frontend == 'pipedMaterial') {
+        invidiousDiv.style.display = 'none';
+        pipedDiv.style.display = 'none';
+        pipedMaterialDiv.style.display = 'block';
+        freetubeYatteeDiv.style.display = 'none';
+    }
+    else if (frontend == 'freetube' || frontend == 'yatte') {
+        invidiousDiv.style.display = 'none';
+        pipedDiv.style.display = 'none';
+        pipedMaterialDiv.style.display = 'none';
+        freetubeYatteeDiv.style.display = 'block';
+        changeYoutubeEmbedFrontendsSettings();
+    }
+}
+
+function changeYoutubeEmbedFrontendsSettings() {
+    if (youtubeEmbedFrontend.value == 'invidious') {
+        pipedDiv.style.display = 'none';
+        pipedMaterialDiv.style.display = 'none';
+        invidiousDiv.style.display = 'block';
+    }
+    if (youtubeEmbedFrontend.value == 'piped') {
+        pipedDiv.style.display = 'block';
+        pipedMaterialDiv.style.display = 'none';
+        invidiousDiv.style.display = 'none';
+    }
+    if (youtubeEmbedFrontend.value == 'pipedMaterial') {
+        pipedDiv.style.display = 'none';
+        pipedMaterialDiv.style.display = 'block';
+        invidiousDiv.style.display = 'none';
+    }
+    else if (youtubeEmbedFrontend.value == 'youtube') {
+        pipedDiv.style.display = 'none';
+        pipedMaterialDiv.style.display = 'none';
+        invidiousDiv.style.display = 'none';
+    }
+}
+
+function changeProtocolSettings() {
+    const normalPipedDiv = document.getElementById('piped').getElementsByClassName("normal")[0];
+    const torPipedDiv = document.getElementById('piped').getElementsByClassName("tor")[0];
+
+    const normalPipedMaterialDiv = document.getElementById('pipedMaterial').getElementsByClassName("normal")[0];
+    const torPipedMaterialDiv = document.getElementById('pipedMaterial').getElementsByClassName("tor")[0];
+
+    const normalInvidiousDiv = document.getElementById('invidious').getElementsByClassName("normal")[0];
+    const torInvidiousDiv = document.getElementById('invidious').getElementsByClassName("tor")[0];
+
+    if (protoco.value == 'normal') {
+        normalInvidiousDiv.style.display = 'block';
+        torInvidiousDiv.style.display = 'none';
+
+        normalPipedDiv.style.display = 'block';
+        torPipedDiv.style.display = 'none';
+
+        normalPipedMaterialDiv.style.display = 'block';
+        torPipedMaterialDiv.style.display = 'none';
+    }
+    else if (protoco.value == 'tor') {
+        normalInvidiousDiv.style.display = 'none';
+        torInvidiousDiv.style.display = 'block';
+
+        normalPipedDiv.style.display = 'none';
+        torPipedDiv.style.display = 'block';
+
+        normalPipedMaterialDiv.style.display = 'none';
+        torPipedMaterialDiv.style.display = 'block';
+    }
+}
+
+document.addEventListener("change", async () => {
+    await browser.storage.local.set({
+        disableYoutube: !disableYoutube.checked,
+        youtubeFrontend: youtubeFrontend.value,
+        youtubeEmbedFrontend: youtubeEmbedFrontend.value,
+        OnlyEmbeddedVideo: OnlyEmbeddedVideo.value,
+        youtubeProtocol: protoco.value,
+    })
+    changeProtocolSettings();
+    changeYoutubeEmbedFrontendsSettings();
+    changeFrontendsSettings();
+})
+
+browser.storage.local.get(
+    [
+        "disableYoutube",
+        "OnlyEmbeddedVideo",
+        "youtubeRedirects",
+        "youtubeFrontend",
+
+        "youtubeEmbedFrontend",
+        "youtubeProtocol",
+    ],
+    r => {
+        disableYoutube.checked = !r.disableYoutube;
+        OnlyEmbeddedVideo.value = r.OnlyEmbeddedVideo;
+        youtubeFrontend.value = r.youtubeFrontend;
+        protoco.value = r.youtubeProtocol;
+
+        changeFrontendsSettings();
+        changeProtocolSettings();
+
+        youtubeEmbedFrontend.value = youtubeEmbedFrontend.value
+        if (r.youtubeFrontend == "freetube" || r.youtubeFrontend == "yatte") changeYoutubeEmbedFrontendsSettings()
+    }
+);
+
+const invidiousForm = invidiousDiv.getElementsByTagName('form')[0];
+const invidiousCookies = invidiousForm.getElementsByTagName('input')[0];
+invidiousForm.addEventListener('submit', async event => {
+    event.preventDefault();
+    const url = new URL(invidiousCookies.value);
+    youtubeHelper.initInvidiousCookies(url);
+});
+
+// const pipedForm = pipedDiv.getElementsByTagName('form')[0];
+// const pipedCookies = pipedForm.getElementsByTagName('input')[0];
+// pipedForm.addEventListener('submit', async event => {
+//     event.preventDefault();
+//     const url = new URL(pipedCookies.value);
+//     youtubeHelper.applyPipedLocalStorage(url);
+// });
+
+utils.processDefaultCustomInstances('youtube', 'invidious', 'normal', document);
+utils.processDefaultCustomInstances('youtube', 'invidious', 'tor', document);
+utils.processDefaultCustomInstances('youtube', 'pipedMaterial', 'normal', document);
+utils.processDefaultCustomInstances('youtube', 'pipedMaterial', 'tor', document);
+utils.processDefaultCustomInstances('youtube', 'piped', 'normal', document);
+utils.processDefaultCustomInstances('youtube', 'piped', 'tor', document);
+
+utils.latency('youtube', 'invidious', document, location, true)
+utils.latency('youtube', 'piped', document, location, true)
+utils.latency('youtube', 'pipedMaterial', document, location, true)
diff --git a/src/pages/options/widgets/youtube.pug b/src/pages/options/widgets/youtube.pug
new file mode 100644
index 00000000..71bf104b
--- /dev/null
+++ b/src/pages/options/widgets/youtube.pug
@@ -0,0 +1,73 @@
+section#youtube_page.option-block
+    .some-block.option-block
+        h1(data-localise="__MSG_youtube__") YouTube
+    hr
+    .some-block.option-block
+        h4(data-localise="__MSG_enable__") Enable
+        input#disable-invidious(type="checkbox")
+
+    .some-block.option-block
+        h4(data-localise="__MSG_frontend__") Frontend
+        select#youtube-frontend
+            option(value="invidious") Invidious
+            option(value="piped") Piped
+            option(value="pipedMaterial") Piped-Material
+            option(value="freetube") FreeTube
+            option(value="yatte") Yattee
+
+    #freetube-yatte
+        .some-block.option-block
+            h4(data-localise="__MSG_embeddedVids__") Embedded Videos Frontend
+            select#youtube-embed-frontend
+                option(value="invidious") Invidious
+                option(value="piped") Piped
+                option(value="pipedMaterial") Piped-Material
+                option(value="youtube") Youtube
+
+    #invidious-piped-pipedMaterial
+        .some-block.option-block
+            h4(data-localise="__MSG_protocol__") Protocol
+            select#protocol
+                option(value="normal" data-localise="__MSG_normal__") Normal
+                option(value="tor" data-localise="__MSG_tor__") Tor
+
+        .some-block.option-block
+            h4(data-localise="__MSG_redirectType__") Redirect Type
+            select#only-embed
+                option(value="both" data-localise="__MSG_both__") both
+                option(value="onlyEmbedded" data-localise="__MSG_onlyEmbedded__") Only Embedded
+                option(value="onlyNotEmbedded" data-localise="__MSG_onlyNotEmbedded__") Only Not Embedded
+
+    #invidious
+        hr
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://invidious.com')
+            include ../../widgets/latency.pug
+            +latency('invidious')
+        .tor
+            include ../../widgets/instances.pug
+            +instances('https://invidious.onion')
+
+    #piped
+        hr
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://piped.com')
+            +latency('piped')
+        .tor
+            include ../../widgets/instances.pug
+            +instances('https://piped.onion')
+
+    #pipedMaterial
+        hr
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://piped-material.com')
+            +latency('pipedMaterial')
+        .tor
+            include ../../widgets/instances.pug
+            +instances('https://piped-material.onion')
+
+
+    script(type="module" src="./widgets/youtube.js")
diff --git a/src/pages/options/widgets/youtubeMusic.js b/src/pages/options/widgets/youtubeMusic.js
new file mode 100644
index 00000000..9a9bf8fb
--- /dev/null
+++ b/src/pages/options/widgets/youtubeMusic.js
@@ -0,0 +1,23 @@
+import youtubeMusicHelper from "../../../assets/javascripts/youtubeMusic.js";
+import utils from "../../../assets/javascripts/utils.js";
+
+let disableYoutubeMusicElement = document.getElementById("disable-beatbump");
+
+browser.storage.local.get(
+    [
+        "disableYoutubeMusic",
+    ],
+    r => {
+        disableYoutubeMusicElement.checked = !r.disableYoutubeMusic;
+    }
+);
+
+document.addEventListener("change", async () => {
+    await browser.storage.local.set({
+        disableYoutubeMusic: !disableYoutubeMusicElement.checked,
+    })
+})
+
+utils.processDefaultCustomInstances('youtubeMusic', 'beatbump', 'normal', document);
+
+utils.latency('youtubeMusic', 'beatbump', document, location)
\ No newline at end of file
diff --git a/src/pages/options/widgets/youtubeMusic.pug b/src/pages/options/widgets/youtubeMusic.pug
new file mode 100644
index 00000000..231b6caf
--- /dev/null
+++ b/src/pages/options/widgets/youtubeMusic.pug
@@ -0,0 +1,17 @@
+section#youtubeMusic_page.option-block
+    .some-block.option-block
+        h1(data-localise="__MSG_ytmusic__") YouTube Music
+    hr
+    .some-block.option-block
+        h4(data-localise="__MSG_enable__") Enable
+        input#disable-beatbump(type="checkbox")
+
+    #beatbump
+        hr
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://beatbump.wewe')
+            include ../../widgets/latency.pug
+            +latency()
+
+    script(type="module" src="./widgets/youtubeMusic.js")