about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/assets/images/quora.pngbin0 -> 5499 bytes
-rw-r--r--src/assets/javascripts/general.js2
-rw-r--r--src/assets/javascripts/quora.js160
-rw-r--r--src/assets/javascripts/utils.js4
-rw-r--r--src/assets/javascripts/youtube/youtube.js5
-rw-r--r--src/instances/data.json18
-rw-r--r--src/instances/get_instances.py22
-rw-r--r--src/pages/background/background.js4
-rw-r--r--src/pages/options/index.html79
-rw-r--r--src/pages/options/index.pug1
-rw-r--r--src/pages/options/widgets/general.js2
-rw-r--r--src/pages/options/widgets/general.pug6
-rw-r--r--src/pages/options/widgets/quora.js42
-rw-r--r--src/pages/options/widgets/quora.pug26
-rw-r--r--src/pages/popup/popup.html4
-rw-r--r--src/pages/popup/popup.js4
-rw-r--r--src/pages/popup/popup.pug6
-rw-r--r--src/pages/widgets/links.pug4
18 files changed, 383 insertions, 6 deletions
diff --git a/src/assets/images/quora.png b/src/assets/images/quora.png
new file mode 100644
index 00000000..d2a06954
--- /dev/null
+++ b/src/assets/images/quora.png
Binary files differdiff --git a/src/assets/javascripts/general.js b/src/assets/javascripts/general.js
index b6bf825d..7b643cfa 100644
--- a/src/assets/javascripts/general.js
+++ b/src/assets/javascripts/general.js
@@ -40,6 +40,7 @@ async function initDefaults() {
                 "reddit",
                 "search",
                 "medium",
+                "quora",
                 "translate",
                 "maps",
             ],
@@ -62,6 +63,7 @@ const allPopupFrontends = [
     "maps",
     "wikipedia",
     "medium",
+    "quora",
     "peertube",
     "lbry",
     "sendTargets"
diff --git a/src/assets/javascripts/quora.js b/src/assets/javascripts/quora.js
new file mode 100644
index 00000000..ecd305f0
--- /dev/null
+++ b/src/assets/javascripts/quora.js
@@ -0,0 +1,160 @@
+window.browser = window.browser || window.chrome;
+
+import utils from './utils.js'
+
+const targets = [
+    /^https?:\/{2}(www\.|)quora\.com.*/
+];
+
+let redirects = {
+    "quetre": {
+        "normal": [],
+        "tor": []
+    }
+}
+function setRedirects(val) {
+    browser.storage.local.get('cloudflareBlackList', r => {
+        redirects.quetre = val;
+        quetreNormalRedirectsChecks = [...redirects.quetre.normal];
+        for (const instance of r.cloudflareBlackList) {
+            const a = quetreNormalRedirectsChecks.indexOf(instance);
+            if (a > -1) quetreNormalRedirectsChecks.splice(a, 1);
+        }
+        browser.storage.local.set({
+            quoraRedirects: redirects,
+            quetreNormalRedirectsChecks
+        })
+    })
+}
+
+let
+    disableQuora,
+    quoraProtocol,
+    quoraRedirects,
+    quetreNormalRedirectsChecks,
+    quetreNormalCustomRedirects,
+    quetreTorRedirectsChecks,
+    quetreTorCustomRedirects;
+
+function init() {
+    return new Promise(async resolve => {
+        browser.storage.local.get(
+            [
+                "disableQuora",
+                "quoraProtocol",
+                "quoraRedirects",
+                "quetreNormalRedirectsChecks",
+                "quetreNormalCustomRedirects",
+                "quetreTorRedirectsChecks",
+                "quetreTorCustomRedirects",
+            ],
+            r => {
+                disableQuora = r.disableQuora;
+                quoraProtocol = r.quoraProtocol;
+                quoraRedirects = r.quoraRedirects;
+                quetreNormalRedirectsChecks = r.quetreNormalRedirectsChecks;
+                quetreNormalCustomRedirects = r.quetreNormalCustomRedirects;
+                quetreTorRedirectsChecks = r.quetreTorRedirectsChecks;
+                quetreTorCustomRedirects = r.quetreTorCustomRedirects;
+                resolve();
+            }
+        )
+    })
+}
+
+init();
+browser.storage.onChanged.addListener(init)
+
+// https://www.quora.com/@keysikaspol/video/7061265241887345946
+// https://www.quora.com/@keysikaspol
+function redirect(url, type, initiator) {
+    if (disableQuora) return;
+    if (type != "main_frame") return;
+    const all = [
+        ...quoraRedirects.quetre.normal,
+        ...quetreNormalCustomRedirects
+    ];
+    if (initiator && (all.includes(initiator.origin) || targets.includes(initiator.host))) return;
+    if (!targets.some(rx => rx.test(url.href))) return;
+
+    let instancesList;
+    if (quoraProtocol == 'normal') instancesList = [...quetreNormalRedirectsChecks, ...quetreNormalCustomRedirects];
+    if (quoraProtocol == 'tor') instancesList = [...quetreTorRedirectsChecks, ...quetreTorCustomRedirects];
+    if (instancesList.length === 0) return;
+
+    const randomInstance = utils.getRandomInstance(instancesList);
+    return `${randomInstance}${url.pathname}`;
+}
+
+function reverse(url) {
+    return new Promise(async resolve => {
+        await init();
+        let protocolHost = utils.protocolHost(url);
+        const all = [
+            ...quoraRedirects.quetre.normal,
+            ...quoraRedirects.quetre.tor,
+            ...quetreNormalCustomRedirects,
+            ...quetreTorCustomRedirects
+        ];
+        if (!all.includes(protocolHost)) { resolve(); return; }
+
+        resolve(`https://quora.com${url.pathname}${url.search}`);
+    })
+}
+
+function switchInstance(url) {
+    return new Promise(async resolve => {
+        await init();
+        let protocolHost = utils.protocolHost(url);
+        const all = [
+            ...quoraRedirects.quetre.tor,
+            ...quoraRedirects.quetre.normal,
+
+            ...quetreNormalCustomRedirects,
+            ...quetreTorCustomRedirects,
+        ];
+        if (!all.includes(protocolHost)) { resolve(); return; }
+
+        let instancesList;
+        if (quoraProtocol == 'normal') instancesList = [...quetreNormalCustomRedirects, ...quetreNormalRedirectsChecks];
+        else if (quoraProtocol == 'tor') instancesList = [...quetreTorCustomRedirects, ...quetreTorRedirectsChecks];
+
+        const i = instancesList.indexOf(protocolHost);
+        if (i > -1) instancesList.splice(i, 1);
+        if (instancesList.length === 0) { resolve(); return; }
+
+        const randomInstance = utils.getRandomInstance(instancesList);
+        resolve(`${randomInstance}${url.pathname}${url.search}`);
+    })
+}
+
+function initDefaults() {
+    return new Promise(async resolve => {
+        fetch('/instances/data.json').then(response => response.text()).then(async data => {
+            let dataJson = JSON.parse(data);
+            redirects.quetre = dataJson.quetre;
+            browser.storage.local.set({
+                disableQuora: false,
+                quoraProtocol: "normal",
+
+                quoraRedirects: redirects,
+
+                quetreNormalRedirectsChecks: [...redirects.quetre.normal],
+                quetreNormalCustomRedirects: [],
+
+                quetreTorRedirectsChecks: [...redirects.quetre.tor],
+                quetreTorCustomRedirects: [],
+            }, () => resolve());
+        });
+    })
+}
+
+export default {
+    setRedirects,
+
+    redirect,
+    reverse,
+    switchInstance,
+
+    initDefaults
+};
diff --git a/src/assets/javascripts/utils.js b/src/assets/javascripts/utils.js
index e0b9ec9b..53a5bb2e 100644
--- a/src/assets/javascripts/utils.js
+++ b/src/assets/javascripts/utils.js
@@ -11,6 +11,7 @@ import peertubeHelper from "./peertube.js";
 import lbryHelper from "./lbry.js";
 import sendTargetsHelper from "./sendTargets.js";
 import tiktokHelper from "./tiktok.js";
+import quoraHelper from "./quora.js"
 import imgurHelper from "./imgur.js";
 import localise from './localise.js'
 
@@ -47,6 +48,7 @@ function updateInstances() {
       searchHelper.setRedirects({ 'searx': instances.searx, 'searxng': instances.searxng, 'whoogle': instances.whoogle });
       wikipediaHelper.setRedirects(instances.wikiless);
       mediumHelper.setRedirects(instances.scribe);
+      quoraHelper.setRedirects(instances.query);
       sendTargetsHelper.setRedirects(instances.send);
       tiktokHelper.setRedirects(instances.proxiTok);
 
@@ -363,6 +365,7 @@ function copyRaw(test, copyRawElement) {
           if (!newUrl) newUrl = await twitterHelper.reverse(url);
           if (!newUrl) newUrl = await instagramHelper.reverse(url);
           if (!newUrl) newUrl = await tiktokHelper.reverse(url);
+          if (!newUrl) newUrl = await quoraHelper.reverse(url);
           if (!newUrl) newUrl = await imgurHelper.reverse(url);
 
           if (newUrl) {
@@ -435,6 +438,7 @@ function switchInstance(test) {
         if (!newUrl) newUrl = await searchHelper.switchInstance(url);
         if (!newUrl) newUrl = await translateHelper.switchInstance(url);
         if (!newUrl) newUrl = await mediumHelper.switchInstance(url);
+        if (!newUrl) newUrl = await quoraHelper.switchInstance(url);
         if (!newUrl) newUrl = await tiktokHelper.switchInstance(url);
         if (!newUrl) newUrl = await sendTargetsHelper.switchInstance(url);
         if (!newUrl) newUrl = await peertubeHelper.switchInstance(url);
diff --git a/src/assets/javascripts/youtube/youtube.js b/src/assets/javascripts/youtube/youtube.js
index 9caf6752..e11578ff 100644
--- a/src/assets/javascripts/youtube/youtube.js
+++ b/src/assets/javascripts/youtube/youtube.js
@@ -445,8 +445,9 @@ function removeXFrameOptions(e) {
         let newSecurity = '';
         for (const item of securityPolicyList) {
           if (item.trim() == '') continue
-          console.log('item', item);
-          let [, key, vals] = item.match(/([a-z-]{0,}) (.*)/);
+          let regex = item.match(/([a-z-]{0,}) (.*)/)
+          if (regex == null) continue
+          let [, key, vals] = regex;
           if (key == 'frame-src') vals = vals + ' ' + instancesList.join(' ');
           newSecurity += key + ' ' + vals + '; ';
         }
diff --git a/src/instances/data.json b/src/instances/data.json
index 6b717969..07a11e8a 100644
--- a/src/instances/data.json
+++ b/src/instances/data.json
@@ -316,6 +316,14 @@
     ],
     "tor": []
   },
+  "quetre": {
+    "normal": [
+      "https://quetre.herokuapp.com",
+      "https://quora.vern.cc",
+      "https://quetre.pussthecat.org"
+    ],
+    "tor": []
+  },
   "simplyTranslate": {
     "normal": [
       "https://simplytranslate.org",
@@ -357,7 +365,6 @@
   "searx": {
     "tor": [
       "http://3afisqjw2rxm6z7mmstyt5rx75qfqrgxnkzftknbp2vhipr2nrmrjdyd.onion",
-      "http://4n53nafyi77iplnbrpmxnp3x4exbswwxigujaxy3b37fvr7bvlopxeyd.onion",
       "http://z34ambyi6makk6ta7ksog2sljly2ctt2sa3apekb7wkllk72sxecdtad.onion",
       "http://yra4tke2pwcnatxjkufpw6kvebu3h3ti2jca2lcdpgx3mpwol326lzid.onion",
       "http://z5vawdol25vrmorm4yydmohsd4u6rdoj2sylvoi3e3nqvxkvpqul7bqd.onion",
@@ -371,7 +378,6 @@
     ],
     "normal": [
       "https://anon.sx",
-      "https://asowneryt.cloudns.nz",
       "https://dynabyte.ca",
       "https://jsearch.pw",
       "https://nibblehole.com",
@@ -390,7 +396,6 @@
       "https://searx.josie.lol",
       "https://searx.kujonello.cf",
       "https://searx.mastodontech.de",
-      "https://searx.mha.fi",
       "https://searx.mxchange.org",
       "https://searx.nakhan.net",
       "https://searx.netzspielplatz.de",
@@ -427,7 +432,9 @@
   "searxng": {
     "tor": [
       "http://w5rl6wsd7mzj4bdkbuqvzidet5osdsm5jhg2f7nvfidakfq5exda5wid.onion",
+      "http://4n53nafyi77iplnbrpmxnp3x4exbswwxigujaxy3b37fvr7bvlopxeyd.onion",
       "http://fpamcnxokg4lzz6b2y7jdwoujmnixfxrh7ptddehctqzoptn4wpdvjid.onion",
+      "http://gbat2pbpg7ys3fi3pbp64667tt5x66mg45xok35bxdw7v55brm7a27yd.onion",
       "http://searxdr3pqz4nydgnqocsia2xbywptxbkympa2emn7zlgggrir4bkfad.onion",
       "http://searx.micohauwkjbyw5meacrb4ipicwvwg4xtzl7y7viv53kig2mdcsvwkyyd.onion",
       "http://rq2w52kyrif3xpfihkgjnhqm3a5aqhoikpv72z3drpjglfzc2wr5z4yd.onion",
@@ -435,6 +442,7 @@
     ],
     "i2p": [],
     "normal": [
+      "https://asowneryt.cloudns.nz",
       "https://darmarit.org/searx",
       "https://etsi.me",
       "https://northboot.xyz",
@@ -449,6 +457,7 @@
       "https://search.privacyguides.net",
       "https://search.rabbit-company.com",
       "https://search.roombob.cat",
+      "https://search.sapti.me",
       "https://search.vojkovic.xyz",
       "https://search.zzls.xyz",
       "https://searx.albony.xyz",
@@ -458,6 +467,7 @@
       "https://searx.fmac.xyz",
       "https://searx.gnous.eu",
       "https://searx.loafland.xyz",
+      "https://searx.mha.fi",
       "https://searx.namejeff.xyz",
       "https://searx.orion-hub.fr",
       "https://searx.ppeb.me",
@@ -515,6 +525,7 @@
     ]
   },
   "peertube": [
+    "https://syop.tv",
     "https://watch.thelema.social",
     "https://tube.miegl.cz",
     "https://mov.clov.fr",
@@ -891,7 +902,6 @@
     "https://phoenixproject.group",
     "https://peertube.sebu77.com",
     "https://www.orion-hub.fr",
-    "https://quantube.win",
     "https://tv.orion-serv.fr",
     "https://video.interru.io",
     "https://tube.cnr.it",
diff --git a/src/instances/get_instances.py b/src/instances/get_instances.py
index b6bba606..18870f32 100644
--- a/src/instances/get_instances.py
+++ b/src/instances/get_instances.py
@@ -239,6 +239,27 @@ def scribe():
     print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'Scribe')
 
 
+def quetre():
+    r = requests.get(
+        'https://raw.githubusercontent.com/zyachel/quetre/main/README.md')
+    _list = {}
+    _list['normal'] = []
+    _list['tor'] = []
+
+    tmp = re.findall(
+        r"\| \[.*\]\(([-a-zA-Z0-9@:%_\+.~#?&//=]{2,}\.[a-z]{2,}\b(?:\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?)\)*\|*[A-Z]{0,}.*\|.*\|", r.text)
+
+    tmp = filterLastSlash(tmp)
+
+    for item in tmp:
+        if item.endswith('.onion'):
+            _list['tor'].append(item)
+        else:
+            _list['normal'].append(item)
+    mightyList['quetre'] = _list
+    print(Fore.GREEN + 'Fetched ' + Style.RESET_ALL + 'Quetre')
+
+
 def simplytranslate():
     r = requests.get('https://simple-web.org/instances/simplytranslate')
     simplyTranslateList = {}
@@ -370,6 +391,7 @@ libreddit()
 teddit()
 wikiless()
 scribe()
+quetre()
 simplytranslate()
 linvgatranslate()
 searx_searxng()
diff --git a/src/pages/background/background.js b/src/pages/background/background.js
index a1ac27db..07e7512e 100644
--- a/src/pages/background/background.js
+++ b/src/pages/background/background.js
@@ -18,6 +18,7 @@ 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";
+import quoraHelper from "../../assets/javascripts/quora.js";
 
 window.browser = window.browser || window.chrome;
 
@@ -41,6 +42,7 @@ browser.runtime.onInstalled.addListener(
                     searchHelper.initDefaults();
                     translateHelper.initDefaults();
                     mediumHelper.initDefaults();
+                    quoraHelper.initDefaults();
                     redditHelper.initDefaults();
                     wikipediaHelper.initDefaults();
                     imgurHelper.initDefaults();
@@ -98,6 +100,7 @@ browser.webRequest.onBeforeRequest.addListener(
     if (!newUrl) newUrl = mapsHelper.redirect(url, initiator);
     if (!newUrl) newUrl = redditHelper.redirect(url, details.type, initiator);
     if (!newUrl) newUrl = mediumHelper.redirect(url, details.type, initiator);
+    if (!newUrl) newUrl = quoraHelper.redirect(url, details.type, initiator);
     if (!newUrl) newUrl = imgurHelper.redirect(url, details.type, initiator);
     if (!newUrl) newUrl = tiktokHelper.redirect(url, details.type, initiator);
     if (!newUrl) newUrl = sendTargetsHelper.redirect(url, details.type, initiator);
@@ -174,6 +177,7 @@ async function redirectOfflineInstance(url, tabId) {
   if (!newUrl) newUrl = await searchHelper.switchInstance(url);
   if (!newUrl) newUrl = await translateHelper.switchInstance(url);
   if (!newUrl) newUrl = await mediumHelper.switchInstance(url);
+  if (!newUrl) newUrl = await quoraHelper.switchInstance(url);
   if (!newUrl) newUrl = await tiktokHelper.switchInstance(url);
   if (!newUrl) newUrl = await imgurHelper.switchInstance(url);
   if (!newUrl) newUrl = await wikipediaHelper.switchInstance(url);
diff --git a/src/pages/options/index.html b/src/pages/options/index.html
index 8d19b3a4..dd09950b 100644
--- a/src/pages/options/index.html
+++ b/src/pages/options/index.html
@@ -30,6 +30,7 @@
                   <ellipse cx="1682" cy="502" rx="88" ry="424"></ellipse>
                 </svg><a href="#medium" data-localise="__MSG_medium__">Medium</a>
           </div>
+          <div class="title"><img src="../../../assets/images/quora.png"><a href="#quora" data-localise="__MSG_quora__">Quora</a></div>
           <div class="title"> <img src="../../../assets/images/peertube-icon.svg"><a href="#peertube" data-localise="__MSG_peertube__">PeerTube</a></div>
           <div class="title"> <img src="../../../assets/images/lbry-icon.png"><a href="#lbry" data-localise="__MSG_lbry__">LBRY/Odysee</a></div>
           <div class="title"> 
@@ -210,6 +211,12 @@
             <input id="medium" type="checkbox">
           </div>
           <div> 
+            <div> <img src="../../../assets/images/quora.png">
+              <x data-localise="__MSG_quora__">Quora</x>
+            </div>
+            <input id="quora" type="checkbox">
+          </div>
+          <div> 
             <div> <img src="../../../assets/images/peertube-icon.svg">
               <x data-localise="__MSG_peertube__">PeerTube</x>
             </div>
@@ -1097,6 +1104,78 @@
         </div>
         <script type="module" src="./widgets/medium.js"></script>
       </section>
+      <section class="option-block" id="quora_page">
+        <div class="some-block option-block">
+          <h1 data-localise="__MSG_quora__">Quora</h1>
+        </div>
+        <hr>
+        <div class="some-block option-block">
+          <h4 data-localise="__MSG_enable__">Enable</h4>
+          <input id="quora-enable" type="checkbox">
+        </div>
+        <div class="some-block option-block">
+          <h4 data-localise="__MSG_protocol__">Protocol</h4>
+          <select id="quora-protocol">
+            <option value="normal" data-localise="__MSG_normal__">Normal</option>
+            <option value="tor" data-localise="__MSG_tor__">Tor</option>
+          </select>
+        </div>
+        <div id="quetre">
+          <hr>
+          <div class="normal">
+                        <div class="some-block option-block">
+                          <h4 data-localise="__MSG_defaultInstances__">Default Instances</h4>
+                        </div>
+                        <div class="checklist"></div>
+                        <hr>
+                        <div class="some-block option-block">
+                          <h4 data-localise="__MSG_customInstances__">Custom Instances</h4>
+                        </div>
+                        <form class="custom-instance-form">
+                          <div class="some-block option-block">
+                            <input class="custom-instance" placeholder="https://quetre.com" type="url">
+                            <button class="add add-instance" type="submit">
+                              <svg xmlns="https://www.w3.org/2000/svg" height="20px" viewBox="0 0 24 24" width="20px" fill="currentColor">
+                                <path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"></path>
+                              </svg>
+                            </button>
+                          </div>
+                        </form>
+                        <div class="checklist custom-checklist"></div>
+                        <div class="buttons buttons-inline">
+                          <label class="button button-inline" id="latency-quetre-label" for="latency-quetre"> 
+                            <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"></path>
+                            </svg>&nbsp;
+                            <x data-localise="__MSG_testInstancesLatency__">Test Instances Latency</x>
+                          </label>
+                          <input class="button button-inline" id="latency-quetre" style="display:none;">
+                        </div>
+          </div>
+          <div class="tor">
+                        <div class="some-block option-block">
+                          <h4 data-localise="__MSG_defaultInstances__">Default Instances</h4>
+                        </div>
+                        <div class="checklist"></div>
+                        <hr>
+                        <div class="some-block option-block">
+                          <h4 data-localise="__MSG_customInstances__">Custom Instances</h4>
+                        </div>
+                        <form class="custom-instance-form">
+                          <div class="some-block option-block">
+                            <input class="custom-instance" placeholder="https://quetre.onion" type="url">
+                            <button class="add add-instance" type="submit">
+                              <svg xmlns="https://www.w3.org/2000/svg" height="20px" viewBox="0 0 24 24" width="20px" fill="currentColor">
+                                <path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"></path>
+                              </svg>
+                            </button>
+                          </div>
+                        </form>
+                        <div class="checklist custom-checklist"></div>
+          </div>
+        </div>
+        <script type="module" src="./widgets/quora.js"></script>
+      </section>
       <section class="option-block" id="peertube_page">
         <div class="some-block option-block">
           <h1 data-localise="__MSG_peertube__">PeerTube</h1>
diff --git a/src/pages/options/index.pug b/src/pages/options/index.pug
index 6488aced..339b5cbc 100644
--- a/src/pages/options/index.pug
+++ b/src/pages/options/index.pug
@@ -22,6 +22,7 @@ html#elementToShowWithJavaScript(lang="en")
             include ./widgets/imgur.pug
             include ./widgets/wikipedia.pug
             include ./widgets/medium.pug
+            include ./widgets/quora.pug
             include ./widgets/peertube.pug
             include ./widgets/lbry.pug
             include ./widgets/search.pug
diff --git a/src/pages/options/widgets/general.js b/src/pages/options/widgets/general.js
index 6fe01b25..25f668ab 100644
--- a/src/pages/options/widgets/general.js
+++ b/src/pages/options/widgets/general.js
@@ -14,6 +14,7 @@ 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 quoraHelper from "../../../assets/javascripts/quora.js";
 import imgurHelper from "../../../assets/javascripts/imgur.js";
 import tiktokHelper from "../../../assets/javascripts/tiktok.js";
 import sendTargetsHelper from "../../../assets/javascripts/sendTargets.js";
@@ -130,6 +131,7 @@ resetSettings.addEventListener("click",
                   await searchHelper.initDefaults();
                   await translateHelper.initDefaults();
                   await mediumHelper.initDefaults();
+                  await quoraHelper.initDefaults();
                   await redditHelper.initDefaults();
                   await wikipediaHelper.initDefaults();
                   await imgurHelper.initDefaults();
diff --git a/src/pages/options/widgets/general.pug b/src/pages/options/widgets/general.pug
index ac9f6639..4123a7f6 100644
--- a/src/pages/options/widgets/general.pug
+++ b/src/pages/options/widgets/general.pug
@@ -152,6 +152,12 @@ section#general_page.option-block
 
         div 
             div 
+                img(src="../../../assets/images/quora.png")
+                x(data-localise="__MSG_quora__") Quora
+            input#quora(type="checkbox")
+
+        div 
+            div 
                 img(src="../../../assets/images/peertube-icon.svg")
                 x(data-localise="__MSG_peertube__") PeerTube
             input#peertube(type="checkbox")
diff --git a/src/pages/options/widgets/quora.js b/src/pages/options/widgets/quora.js
new file mode 100644
index 00000000..34e84cf1
--- /dev/null
+++ b/src/pages/options/widgets/quora.js
@@ -0,0 +1,42 @@
+import utils from "../../../assets/javascripts/utils.js";
+
+const enable = document.getElementById("quora-enable");
+const protocol = document.getElementById("quora-protocol")
+const quora = document.getElementById('quora_page');
+
+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';
+    }
+}
+
+quora.addEventListener("change", () => {
+    changeProtocolSettings();
+    browser.storage.local.set({
+        disableQuora: !enable.checked,
+        quoraProtocol: protocol.value,
+    })
+})
+
+browser.storage.local.get(
+    [
+        "disableQuora",
+        "quoraProtocol"
+    ],
+    r => {
+        enable.checked = !r.disableQuora;
+        protocol.value = r.quoraProtocol;
+        changeProtocolSettings();
+    }
+)
+
+utils.processDefaultCustomInstances('quora', 'quetre', 'normal', document);
+utils.processDefaultCustomInstances('quora', 'quetre', 'tor', document);
+utils.latency('quora', 'quetre', document, location)
\ No newline at end of file
diff --git a/src/pages/options/widgets/quora.pug b/src/pages/options/widgets/quora.pug
new file mode 100644
index 00000000..8f5fe639
--- /dev/null
+++ b/src/pages/options/widgets/quora.pug
@@ -0,0 +1,26 @@
+section#quora_page.option-block
+    .some-block.option-block
+        h1(data-localise="__MSG_quora__") Quora
+    hr
+    .some-block.option-block
+        h4(data-localise="__MSG_enable__") Enable
+        input#quora-enable(type="checkbox")
+
+    .some-block.option-block
+        h4(data-localise="__MSG_protocol__") Protocol
+        select#quora-protocol
+            option(value="normal" data-localise="__MSG_normal__") Normal
+            option(value="tor" data-localise="__MSG_tor__") Tor
+
+    #quetre
+        hr
+        .normal
+            include ../../widgets/instances.pug
+            +instances('https://quetre.com')
+            include ../../widgets/latency.pug
+            +latency('quetre')
+        .tor
+            include ../../widgets/instances.pug
+            +instances('https://quetre.onion')
+
+    script(type="module" src="./widgets/quora.js")
\ No newline at end of file
diff --git a/src/pages/popup/popup.html b/src/pages/popup/popup.html
index 5b00b084..8555dcac 100644
--- a/src/pages/popup/popup.html
+++ b/src/pages/popup/popup.html
@@ -48,6 +48,10 @@
         <h4 data-localise="__MSG_medium__">Medium</h4></a>
       <input id="disable-medium" type="checkbox">
     </div>
+    <div class="some-block" id="quora"><a class="title" href="https://quora.com"><img src="../../assets/images/quora.png">
+        <h4 data-localise="__MSG_quora__">Quora</h4></a>
+      <input id="disable-quora" type="checkbox">
+    </div>
     <div class="some-block" id="peertube"><a class="title" href="https://search.joinpeertube.org"><img src="../../assets/images/peertube-icon.svg">
         <h4 data-localise="__MSG_peertube__">PeerTube</h4></a>
       <input id="disable-peertube" type="checkbox">
diff --git a/src/pages/popup/popup.js b/src/pages/popup/popup.js
index 17eeb2ca..a25ca6b9 100644
--- a/src/pages/popup/popup.js
+++ b/src/pages/popup/popup.js
@@ -44,6 +44,7 @@ let disableSearchElement = document.getElementById("disable-search");
 let disableElement = document.getElementById("disable-simplyTranslate");
 let disableWikipediaElement = document.getElementById("disable-wikipedia");
 let disableMediumElement = document.getElementById("disable-medium");
+let disableQuoraElement = document.getElementById("disable-quora");
 let disablePeertubeElement = document.getElementById("disable-peertube");
 let disableLbryElement = document.getElementById("disable-lbry");
 let disableSendTargetsElement = document.getElementById("disable-sendTargets");
@@ -64,6 +65,7 @@ browser.storage.local.get(
     "disableImgur",
     "disableTiktok",
     "disableMedium",
+    "disableQuora",
     "disablePeertubeTargets",
     "disableLbryTargets",
     "disableSendTarget",
@@ -83,6 +85,7 @@ browser.storage.local.get(
     disableImgurElement.checked = !r.disableImgur;
     disableTiktokElement.checked = !r.disableTiktok;
     disableMediumElement.checked = !r.disableMedium;
+    disableQuoraElement.checked = !r.disableQuora;
     disablePeertubeElement.checked = !r.disablePeertubeTargets;
     disableLbryElement.checked = !r.disableLbryTargets;
     disableSendTargetsElement.checked = !r.disableSendTarget;
@@ -109,6 +112,7 @@ document.addEventListener("change", () => {
     disableImgur: !disableImgurElement.checked,
     disableTiktok: !disableTiktokElement.checked,
     disableMedium: !disableMediumElement.checked,
+    disableQuora: !disableQuoraElement.checked,
     disablePeertubeTargets: !disablePeertubeElement.checked,
     disableLbryTargets: !disableLbryElement.checked,
     disableSendTarget: !disableSendTargetsElement.checked,
diff --git a/src/pages/popup/popup.pug b/src/pages/popup/popup.pug
index a2c8de93..02d9165e 100644
--- a/src/pages/popup/popup.pug
+++ b/src/pages/popup/popup.pug
@@ -62,6 +62,12 @@ html(lang="en")
                 h4(data-localise="__MSG_medium__") Medium
             input#disable-medium(type="checkbox")
 
+        #quora.some-block
+            a.title(href="https://quora.com")
+                img(src="../../assets/images/quora.png")
+                h4(data-localise="__MSG_quora__") Quora
+            input#disable-quora(type="checkbox")
+
         #peertube.some-block
             a.title(href="https://search.joinpeertube.org")
                 img(src="../../assets/images/peertube-icon.svg")
diff --git a/src/pages/widgets/links.pug b/src/pages/widgets/links.pug
index 7a04a991..256dd9ba 100644
--- a/src/pages/widgets/links.pug
+++ b/src/pages/widgets/links.pug
@@ -42,6 +42,10 @@ mixin links(service)
             +medium
             a(href="#medium" data-localise="__MSG_medium__") Medium
 
+        .title
+            img(src="../../../assets/images/quora.png")
+            a(href="#quora" data-localise="__MSG_quora__") Quora
+
         .title 
             img(src="../../../assets/images/peertube-icon.svg")
             a(href="#peertube" data-localise="__MSG_peertube__") PeerTube