about summary refs log tree commit diff stats
path: root/src/pages
diff options
context:
space:
mode:
Diffstat (limited to 'src/pages')
-rw-r--r--src/pages/background/background.js46
-rw-r--r--src/pages/components/Label.svelte2
-rw-r--r--src/pages/messages_src/App.svelte104
-rw-r--r--src/pages/options_src/General/SettingsButtons.svelte2
-rw-r--r--src/pages/options_src/Services/Instances.svelte93
-rw-r--r--src/pages/options_src/Services/Services.svelte32
-rw-r--r--src/pages/popup_src/Buttons.svelte142
-rw-r--r--src/pages/popup_src/components/Row.svelte23
8 files changed, 236 insertions, 208 deletions
diff --git a/src/pages/background/background.js b/src/pages/background/background.js
index 1fcba190..49bae0bf 100644
--- a/src/pages/background/background.js
+++ b/src/pages/background/background.js
@@ -53,6 +53,7 @@ browser.webRequest.onBeforeRequest.addListener(
     let documentUrl
     try {
       if (details.originUrl) originUrl = new URL(details.originUrl)
+      else if (details.initiator) originUrl = new URL(details.initiator)
       if (details.documentUrl) documentUrl = new URL(details.documentUrl)
     } catch {
       return null
@@ -71,6 +72,7 @@ browser.webRequest.onBeforeRequest.addListener(
       (newUrl && newUrl.startsWith("https://no-instance.libredirect.invalid")) ||
       (!newUrl && url.href.startsWith("https://no-instance.libredirect.invalid"))
     ) {
+      if (details.type != "main_frame") return null
       newUrl = newUrl ? new URL(newUrl) : url
       const frontend = newUrl.searchParams.get("frontend")
       const oldUrl = new URL(newUrl.searchParams.get("url"))
@@ -85,17 +87,16 @@ browser.webRequest.onBeforeRequest.addListener(
       return { cancel: true }
     }
 
-    if (!newUrl) {
-      if (url.href.match(/^https?:\/{2}(.*\.)?libredirect\.invalid.*/)) {
-        const params = new URLSearchParams({
-          message: "disabled",
-          url: url.href,
-        })
-        browser.tabs.update({
-          url: browser.runtime.getURL(`/pages/messages/index.html?${params.toString()}`),
-        })
-        return { cancel: true }
-      }
+    if (!newUrl && url.href.match(/^https?:\/{2}(.*\.)?libredirect\.invalid.*/)) {
+      if (details.type != "main_frame") return null
+      const params = new URLSearchParams({
+        message: "disabled",
+        url: url.href,
+      })
+      browser.tabs.update({
+        url: browser.runtime.getURL(`/pages/messages/index.html?${params.toString()}`),
+      })
+      return { cancel: true }
     }
 
     if (newUrl === "CANCEL") {
@@ -117,29 +118,6 @@ browser.webRequest.onBeforeRequest.addListener(
   ["blocking"]
 )
 
-browser.webRequest.onHeadersReceived.addListener(
-  details => {
-    if (details.statusCode >= 501 || details.statusCode == 429 || details.statusCode == 403) {
-      const url = new URL(details.url)
-      const { service, frontend } = servicesHelper.computeFrontend(url)
-      if (!service) return
-      const params = new URLSearchParams({
-        message: "server_error",
-        code: details.statusCode,
-        url: url.href,
-        frontend: frontend,
-        service: service,
-      })
-      setTimeout(() => {
-        browser.tabs.update({
-          url: browser.runtime.getURL(`/pages/messages/index.html?${params.toString()}`),
-        })
-      }, 2000)
-    }
-  },
-  { urls: ["<all_urls>"] }
-)
-
 browser.tabs.onRemoved.addListener(tabId => {
   if (tabIdRedirects[tabId] != undefined) {
     delete tabIdRedirects[tabId]
diff --git a/src/pages/components/Label.svelte b/src/pages/components/Label.svelte
index 39930cd1..d59b9436 100644
--- a/src/pages/components/Label.svelte
+++ b/src/pages/components/Label.svelte
@@ -1,4 +1,4 @@
-<span>
+<span {...$$restProps}>
   <slot></slot>
 </span>
 
diff --git a/src/pages/messages_src/App.svelte b/src/pages/messages_src/App.svelte
index 1c5170dd..82526530 100644
--- a/src/pages/messages_src/App.svelte
+++ b/src/pages/messages_src/App.svelte
@@ -9,7 +9,6 @@
   import { options, config, page } from "./stores"
   import Button from "../components/Button.svelte"
   import AutoPickIcon from "../icons/AutoPickIcon.svelte"
-  import SwitchInstanceIcon from "../icons/SwitchInstanceIcon.svelte"
 
   let _options
   const unsubscribeOptions = options.subscribe(val => {
@@ -49,70 +48,20 @@
   const oldUrl = new URL(params.get("url"))
 
   async function autoPick() {
-    const frontend = params.get("frontend")
     autoPicking = true
+    const frontend = params.get("frontend")
     const redirects = await utils.getList(_options)
-    const instances = utils.randomInstances(redirects[frontend]["clearnet"], 5)
-    const pings = await Promise.all([
-      ...instances.map(async instance => {
-        return [instance, await utils.ping(instance)]
-      }),
-    ])
-    pings.sort((a, b) => a[1] - b[1])
-    _options[frontend].push(pings[0][0])
+    const clearnet = redirects[frontend]["clearnet"]
+    const instance = await utils.autoPickInstance(clearnet)
+    _options[frontend].push(instance)
     options.set(_options)
     autoPicking = false
   }
 
-  async function autoPickInstance() {
-    await autoPick()
-    await redirectUrl()
-  }
-
-  async function enableService() {
-    const service = await servicesHelper.computeService(oldUrl)
-    _options[service].enabled = true
-    options.set(_options)
-    await redirectUrl()
-  }
-
   async function redirectUrl() {
     const newUrl = await servicesHelper.redirectAsync(oldUrl, "main_frame", null, null, false, true)
     browser.tabs.update({ url: newUrl })
   }
-
-  async function switchInstance() {
-    const newUrl = await servicesHelper.switchInstance(oldUrl)
-    browser.tabs.update({ url: newUrl })
-  }
-
-  async function removeInstance() {
-    const service = await servicesHelper.computeService(oldUrl)
-    const frontend = params.get("frontend")
-    const i = _options[frontend].findIndex(instance => oldUrl.href.startsWith(instance))
-    _options[frontend].splice(i, 1)
-    options.set(_options)
-    const newUrl = await servicesHelper.switchInstance(oldUrl, service)
-    browser.tabs.update({ url: newUrl })
-  }
-
-  async function removeAndAutoPickInstance() {
-    const service = await servicesHelper.computeService(oldUrl)
-
-    const frontend = params.get("frontend")
-    const i = _options[frontend].findIndex(instance => oldUrl.href.startsWith(instance))
-    _options[frontend].splice(i, 1)
-    options.set(_options)
-    await autoPick()
-    const newUrl = await servicesHelper.switchInstance(oldUrl, service)
-    browser.tabs.update({ url: newUrl })
-  }
-
-  async function addAutoPickInstance() {
-    await autoPick()
-    const newUrl = await servicesHelper.switchInstance(oldUrl)
-    browser.tabs.update({ url: newUrl })
-  }
 </script>
 
 {#if _options && _config}
@@ -120,42 +69,27 @@
     {#if params.get("message") == "disabled"}
       <div>
         <h1>You disabled redirections for this service</h1>
-        <Button on:click={enableService}>
+        <Button
+          on:click={async () => {
+            const { service } = await servicesHelper.computeServiceFrontend(oldUrl)
+            _options[service].enabled = true
+            options.set(_options)
+            await redirectUrl()
+          }}
+        >
           {browser.i18n.getMessage("enable") || "Enable"}
         </Button>
       </div>
-    {:else if params.get("message") == "server_error"}
-      <!-- https://httpstat.us/403 for testing -->
-      <div>
-        <h1>Your selected instance gave out an error: {params.get("code")}</h1>
-        {#if _options[params.get("frontend")].length > 1}
-          <Button on:click={switchInstance}>
-            <SwitchInstanceIcon class="margin margin_{document.body.dir}" />
-            {browser.i18n.getMessage("switchInstance") || "Switch Instance"}
-          </Button>
-          <Button on:click={removeInstance}>
-            <SwitchInstanceIcon class="margin margin_{document.body.dir}" />
-            {browser.i18n.getMessage("removeInstance") || "Remove Instance"}
-            +
-            {browser.i18n.getMessage("switchInstance") || "Switch Instance"}
-          </Button>
-        {:else}
-          <Button on:click={addAutoPickInstance} disabled={autoPicking}>
-            <AutoPickIcon class="margin margin_{document.body.dir}" />
-            {browser.i18n.getMessage("autoPickInstance") || "Auto Pick Instance"}
-          </Button>
-          <Button on:click={removeAndAutoPickInstance} disabled={autoPicking}>
-            <AutoPickIcon class="margin margin_{document.body.dir}" />
-            {browser.i18n.getMessage("removeInstance") || "Remove Instance"}
-            +
-            {browser.i18n.getMessage("autoPickInstance") || "Auto Pick Instance"}
-          </Button>
-        {/if}
-      </div>
     {:else if params.get("message") == "no_instance"}
       <div>
         <h1>You have no instance selected for this frontend</h1>
-        <Button on:click={autoPickInstance} disabled={autoPicking}>
+        <Button
+          on:click={async () => {
+            await autoPick()
+            await redirectUrl()
+          }}
+          disabled={autoPicking}
+        >
           <AutoPickIcon class="margin margin_{document.body.dir}" />
           {browser.i18n.getMessage("autoPickInstance") || "Auto Pick Instance"}
         </Button>
diff --git a/src/pages/options_src/General/SettingsButtons.svelte b/src/pages/options_src/General/SettingsButtons.svelte
index 4be747fe..1b92ecbc 100644
--- a/src/pages/options_src/General/SettingsButtons.svelte
+++ b/src/pages/options_src/General/SettingsButtons.svelte
@@ -38,7 +38,7 @@
     const resultString = JSON.stringify(_options, null, "  ")
     const anchor = document.createElement("a")
     anchor.href = "data:application/json;base64," + btoa(resultString)
-    anchor.download = `libredirect-settings-v${_options.version}.json`
+    anchor.download = `libredirect-settings-v${_options.version}-${(new Date().toISOString().replace(':','-').slice(0,-5))}.json`
     anchor.click()
   }
 
diff --git a/src/pages/options_src/Services/Instances.svelte b/src/pages/options_src/Services/Instances.svelte
index 4e5d1e7d..b37c3904 100644
--- a/src/pages/options_src/Services/Instances.svelte
+++ b/src/pages/options_src/Services/Instances.svelte
@@ -56,30 +56,6 @@
     return true
   }
 
-  async function pingInstances() {
-    pingCache = {}
-    for (const instance of allInstances) {
-      pingCache[instance] = { color: "lightblue", value: "pinging..." }
-      const time = await utils.ping(instance)
-      pingCache[instance] = colorTime(time)
-    }
-  }
-
-  async function autoPickInstance() {
-    const instances = utils.randomInstances(redirects[selectedFrontend]["clearnet"], 5)
-    const myInstancesCache = []
-    for (const instance of instances) {
-      pingCache[instance] = { color: "lightblue", value: "pinging..." }
-      const time = await utils.ping(instance)
-      pingCache[instance] = colorTime(time)
-      myInstancesCache.push([instance, time])
-    }
-    myInstancesCache.sort((a, b) => a[1] - b[1])
-
-    _options[selectedFrontend].push(myInstancesCache[0][0])
-    options.set(_options)
-  }
-
   function colorTime(time) {
     let value
     let color
@@ -113,17 +89,46 @@
       options.set(_options)
     }
   }
+
+  let autoPicking = false
+  let pinging = false
 </script>
 
 {#if serviceConf.frontends[selectedFrontend].instanceList && redirects && blacklist}
   <hr />
 
   <div>
-    <Button on:click={pingInstances}>
+    <Button
+      on:click={async () => {
+        pinging = true
+        pingCache = {}
+        for (const instance of allInstances) {
+          pingCache[instance] = { color: "lightblue", value: "pinging..." }
+          const time = await utils.ping(instance)
+          pingCache[instance] = colorTime(time)
+        }
+        pinging = false
+      }}
+      disabled={pinging}
+    >
       <PingIcon class="margin margin_{document.body.dir}" />
       {browser.i18n.getMessage("pingInstances") || "Ping Instances"}
     </Button>
-    <Button on:click={autoPickInstance}>
+    <Button
+      on:click={async () => {
+        autoPicking = true
+        const clearnet = redirects[selectedFrontend]["clearnet"]
+        for (const instance of _options[selectedFrontend]) {
+          const i = clearnet.indexOf(instance)
+          if (i >= 0) clearnet.splice(i, 1)
+        }
+        const instance = await utils.autoPickInstance(clearnet)
+        _options[selectedFrontend].push(instance)
+        options.set(_options)
+        autoPicking = false
+      }}
+      disabled={autoPicking}
+    >
       <AutoPickIcon class="margin margin_{document.body.dir}" />
       {browser.i18n.getMessage("autoPickInstance") || "Auto Pick Instance"}
     </Button>
@@ -202,20 +207,34 @@
                     <span style="color:{pingCache[instance].color}">{pingCache[instance].value}</span>
                   {/if}
                 </span>
-                <button
-                  class="add"
-                  aria-label="Add instance"
-                  on:click={() => {
-                    if (_options[selectedFrontend]) {
-                      if (!_options[selectedFrontend].includes(instance)) {
+                {#if !_options[selectedFrontend].includes(instance)}
+                  <button
+                    class="add"
+                    aria-label="Add instance"
+                    on:click={() => {
+                      if (_options[selectedFrontend]) {
                         _options[selectedFrontend].push(instance)
                         options.set(_options)
                       }
-                    }
-                  }}
-                >
-                  <AddIcon />
-                </button>
+                    }}
+                  >
+                    <AddIcon />
+                  </button>
+                {:else}
+                  <button
+                    class="add"
+                    aria-label="Remove Instance"
+                    on:click={() => {
+                      const index = _options[selectedFrontend].indexOf(instance)
+                      if (index > -1) {
+                        _options[selectedFrontend].splice(index, 1)
+                        options.set(_options)
+                      }
+                    }}
+                  >
+                    <CloseIcon />
+                  </button>
+                {/if}
               </Row>
               <hr />
             {/each}
diff --git a/src/pages/options_src/Services/Services.svelte b/src/pages/options_src/Services/Services.svelte
index db2977f9..dcc826fa 100644
--- a/src/pages/options_src/Services/Services.svelte
+++ b/src/pages/options_src/Services/Services.svelte
@@ -94,23 +94,23 @@
     />
   </Row>
 
-  <div style={!serviceOptions.enabled && "pointer-events: none;opacity: 0.4;user-select: none;"}>
-    <Row>
-      <Label>{browser.i18n.getMessage("showInPopup") || "Show in popup"}</Label>
-      <Checkbox
-        checked={_options.popupServices.includes(selectedService)}
-        onChange={e => {
-          if (e.target.checked && !_options.popupServices.includes(selectedService)) {
-            _options.popupServices.push(selectedService)
-          } else if (_options.popupServices.includes(selectedService)) {
-            const index = _options.popupServices.indexOf(selectedService)
-            if (index !== -1) _options.popupServices.splice(index, 1)
-          }
-          options.set(_options)
-        }}
-      />
-    </Row>
+  <Row>
+    <Label>{browser.i18n.getMessage("showInPopup") || "Show in popup"}</Label>
+    <Checkbox
+      checked={_options.popupServices.includes(selectedService)}
+      onChange={e => {
+        if (e.target.checked && !_options.popupServices.includes(selectedService)) {
+          _options.popupServices.push(selectedService)
+        } else if (_options.popupServices.includes(selectedService)) {
+          const index = _options.popupServices.indexOf(selectedService)
+          if (index !== -1) _options.popupServices.splice(index, 1)
+        }
+        options.set(_options)
+      }}
+    />
+  </Row>
 
+  <div style={!serviceOptions.enabled && "pointer-events: none;opacity: 0.4;user-select: none;"}>
     <Row>
       <Label>
         <a href={frontendWebsite} style="text-decoration: underline;" target="_blank" rel="noopener noreferrer">
diff --git a/src/pages/popup_src/Buttons.svelte b/src/pages/popup_src/Buttons.svelte
index ab5682dc..2354fcac 100644
--- a/src/pages/popup_src/Buttons.svelte
+++ b/src/pages/popup_src/Buttons.svelte
@@ -12,6 +12,8 @@
   import { onDestroy } from "svelte"
   import servicesHelper from "../../assets/javascripts/services"
   import Switch from "./components/Switch.svelte"
+  import AutoPickIcon from "../icons/AutoPickIcon.svelte"
+  import utils from "../../assets/javascripts/utils"
 
   let _options
   let _config
@@ -27,16 +29,28 @@
   let switchInstance
   let redirectToOriginal
   let redirect
-  let currentService
+  let frontend
+  let service
   browser.tabs.query({ active: true, currentWindow: true }, async tabs => {
     if (tabs[0].url) {
       url = new URL(tabs[0].url)
       servicesHelper.switchInstance(url).then(r => (switchInstance = r))
       servicesHelper.reverse(url).then(r => (redirectToOriginal = r))
       servicesHelper.redirectAsync(url, "main_frame", null, null, false, true).then(r => (redirect = r))
-      servicesHelper.computeService(url).then(r => (currentService = r))
+      servicesHelper.computeServiceFrontend(url).then(r => ({ service, frontend } = r))
     }
   })
+
+  let autoPicking = false
+  async function autoPick() {
+    autoPicking = true
+    const redirects = await utils.getList(_options)
+    const clearnet = redirects[frontend]["clearnet"]
+    const instance = await utils.autoPickInstance(clearnet, url)
+    _options[frontend].push(instance)
+    options.set(_options)
+    autoPicking = false
+  }
 </script>
 
 <div class={document.body.dir}>
@@ -46,32 +60,91 @@
       on:click={() => {
         browser.tabs.query({ active: true, currentWindow: true }, tabs => {
           browser.runtime.sendMessage({ message: "redirect", tabId: tabs[0].id }, () => {
-            browser.tabs.update({ url: redirect })
+            browser.tabs.update({ url: redirect }, () => {
+              window.close()
+            })
           })
         })
       }}
     >
-      <Label>{browser.i18n.getMessage("redirect") || "Redirect"}</Label>
+      <Label class="margin">{browser.i18n.getMessage("redirect") || "Redirect"}</Label>
       <RedirectIcon />
     </Row>
   {/if}
 
-  {#if switchInstance}
-    <Row
-      class="interactive"
-      on:click={async () =>
-        browser.tabs.update({ url: switchInstance }, () => {
-          window.close()
-        })}
-    >
-      <Label>{browser.i18n.getMessage("switchInstance") || "Switch Instance"}</Label>
-      <SwitchInstanceIcon />
-    </Row>
+  {#if service && frontend}
+    {#if _options[frontend].length > 1}
+      {#if switchInstance}
+        <Row
+          class="interactive"
+          on:click={async () =>
+            browser.tabs.update({ url: switchInstance }, () => {
+              window.close()
+            })}
+        >
+          <Label class="margin">{browser.i18n.getMessage("switchInstance") || "Switch Instance"}</Label>
+          <SwitchInstanceIcon />
+        </Row>
+      {/if}
+      <Row
+        class="interactive"
+        on:click={async () => {
+          const i = _options[frontend].findIndex(instance => url.href.startsWith(instance))
+          _options[frontend].splice(i, 1)
+          options.set(_options)
+          const newUrl = await servicesHelper.switchInstance(url, service)
+          browser.tabs.update({ url: newUrl }, () => {
+            window.close()
+          })
+        }}
+      >
+        <Label class="margin">
+          {browser.i18n.getMessage("remove") || "Remove"}
+          +
+          {browser.i18n.getMessage("switchInstance") || "Switch Instance"}
+        </Label>
+        <SwitchInstanceIcon />
+      </Row>
+    {:else}
+      <Row
+        class={"interactive " + (autoPicking ? "disabled" : "")}
+        on:click={async () => {
+          const i = _options[frontend].findIndex(instance => url.href.startsWith(instance))
+          _options[frontend].splice(i, 1)
+          options.set(_options)
+          await autoPick()
+          browser.tabs.update({ url: await servicesHelper.switchInstance(url, service) }, () => {
+            window.close()
+          })
+        }}
+      >
+        <Label class="margin">
+          {browser.i18n.getMessage("remove") || "Remove"}
+          +
+          {browser.i18n.getMessage("autoPickInstance") || "Auto Pick Instance"}
+        </Label>
+        <AutoPickIcon />
+      </Row>
+      <Row
+        class={"interactive " + (autoPicking ? "disabled" : "")}
+        on:click={async () => {
+          await autoPick()
+          browser.tabs.update({ url: await servicesHelper.switchInstance(url, service) }, () => {
+            window.close()
+          })
+        }}
+      >
+        <Label class="margin">
+          {browser.i18n.getMessage("autoPickInstance") || "Auto Pick Instance"}
+        </Label>
+        <AutoPickIcon />
+      </Row>
+    {/if}
   {/if}
 
   {#if redirectToOriginal}
     <Row class="interactive" on:click={() => servicesHelper.copyRaw(url)}>
-      <Label>{browser.i18n.getMessage("copyOriginal") || "Copy Original"}</Label>
+      <Label class="margin">{browser.i18n.getMessage("copyOriginal") || "Copy Original"}</Label>
       <CopyIcon />
     </Row>
     <Row
@@ -79,12 +152,14 @@
       on:click={() => {
         browser.tabs.query({ active: true, currentWindow: true }, tabs => {
           browser.runtime.sendMessage({ message: "reverse", tabId: tabs[0].id }, () => {
-            browser.tabs.update({ url: redirectToOriginal })
+            browser.tabs.update({ url: redirectToOriginal }, () => {
+              window.close()
+            })
           })
         })
       }}
     >
-      <Label>{browser.i18n.getMessage("redirectToOriginal" || "Redirect to Original")}</Label>
+      <Label class="margin">{browser.i18n.getMessage("redirectToOriginal" || "Redirect to Original")}</Label>
       <RedirectToOriginalIcon />
     </Row>
   {/if}
@@ -93,13 +168,13 @@
     <hr />
   {/if}
 
-  {#if currentService}
-    <Switch serviceKey={currentService} {url} />
+  {#if service}
+    <Switch serviceKey={service} {url} />
     <hr />
   {/if}
 
   {#each _options.popupServices as serviceKey}
-    {#if currentService !== serviceKey}
+    {#if service !== serviceKey}
       <Switch {serviceKey} {url} />
     {/if}
   {/each}
@@ -113,7 +188,7 @@
         window.close()
       })}
   >
-    <Label>{browser.i18n.getMessage("settings")}</Label>
+    <Label class="margin">{browser.i18n.getMessage("settings")}</Label>
     <SettingsIcon />
   </Row>
 </div>
@@ -130,6 +205,20 @@
     transform: translateY(1px);
   }
 
+  :global(.disabled) {
+    cursor: not-allowed;
+    opacity: 0.5;
+  }
+
+  :global(.disabled:hover) {
+    color: var(--text);
+    cursor: not-allowed;
+  }
+
+  :global(.disabled:active) {
+    transform: none;
+  }
+
   :global(img, svg) {
     margin-right: 5px;
     margin-left: 0;
@@ -142,4 +231,13 @@
     margin-right: 0;
     margin-left: 5px;
   }
+
+  :global(.margin) {
+    margin-right: 5px;
+    margin-left: 0;
+  }
+  :global(.margin_rtl) {
+    margin-right: 0;
+    margin-left: 5px;
+  }
 </style>
diff --git a/src/pages/popup_src/components/Row.svelte b/src/pages/popup_src/components/Row.svelte
index a4d78f07..064942da 100644
--- a/src/pages/popup_src/components/Row.svelte
+++ b/src/pages/popup_src/components/Row.svelte
@@ -1,13 +1,12 @@
 <div {...$$props} on:click>
-    <slot></slot>
-  </div>
-  
-  <style>
-    div {
-      justify-content: space-between;
-      display: flex;
-      align-items: center;
-      margin: 10px 0;
-    }
-  </style>
-  
\ No newline at end of file
+  <slot></slot>
+</div>
+
+<style>
+  div {
+    justify-content: space-between;
+    display: flex;
+    align-items: center;
+    margin: 10px 0;
+  }
+</style>