Ahmad Kholid 3 лет назад
Родитель
Сommit
c156ad64e2

+ 44 - 0
src/background/workflow-engine/blocks-handler/handler-switch-tab.js

@@ -0,0 +1,44 @@
+import browser from 'webextension-polyfill';
+import { getBlockConnection } from '../helper';
+
+export default async function ({ data, outputs }) {
+  const nextBlockId = getBlockConnection({ outputs });
+  const generateError = (message, errorData) => {
+    const error = new Error(message);
+    error.nextBlockId = nextBlockId;
+
+    if (errorData) error.data = errorData;
+
+    return error;
+  };
+  this.windowId = null;
+  let [tab] = await browser.tabs.query({ url: data.matchPattern });
+
+  if (!tab) {
+    if (data.createIfNoMatch) {
+      if (!data.url.startsWith('http')) {
+        throw generateError('invalid-active-tab', { url: data.url });
+      }
+
+      tab = await browser.tabs.create({
+        active: true,
+        url: data.url,
+        windowId: this.windowId,
+      });
+    } else {
+      throw generateError('no-match-tab', { pattern: data.matchPattern });
+    }
+  } else {
+    await browser.tabs.update(tab.id, { active: true });
+  }
+
+  this.activeTab.id = tab.id;
+  this.activeTab.frameId = 0;
+  this.activeTab.url = tab.url;
+  this.windowId = tab.windowId;
+
+  return {
+    nextBlockId,
+    data: tab.url,
+  };
+}

+ 59 - 0
src/components/newtab/workflow/edit/EditSwitchTab.vue

@@ -0,0 +1,59 @@
+<template>
+  <div>
+    <ui-input
+      :model-value="data.matchPattern"
+      placeholder="https://example.com/*"
+      class="w-full"
+      @change="updateData({ matchPattern: $event })"
+    >
+      <template #label>
+        {{ t('workflow.blocks.switch-tab.matchPattern') }}
+        <a
+          :title="t('common.example', 2)"
+          href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns#examples"
+          target="_blank"
+          rel="noopener"
+          class="inline-block ml-1"
+        >
+          <v-remixicon
+            name="riInformationLine"
+            class="inline-block"
+            size="18"
+          />
+        </a>
+      </template>
+    </ui-input>
+    <ui-checkbox
+      :model-value="data.createIfNoMatch"
+      class="mt-2"
+      @change="updateData({ createIfNoMatch: $event })"
+    >
+      {{ t('workflow.blocks.switch-tab.createIfNoMatch') }}
+    </ui-checkbox>
+    <ui-input
+      v-if="data.createIfNoMatch"
+      :model-value="data.url"
+      :label="t('workflow.blocks.switch-tab.url')"
+      placeholder="https://example.com"
+      class="w-full mt-2"
+      @change="updateData({ url: $event })"
+    />
+  </div>
+</template>
+<script setup>
+import { useI18n } from 'vue-i18n';
+
+const props = defineProps({
+  data: {
+    type: Object,
+    default: () => ({}),
+  },
+});
+const emit = defineEmits(['update:data']);
+
+const { t } = useI18n();
+
+function updateData(value) {
+  emit('update:data', { ...props.data, ...value });
+}
+</script>

+ 2 - 0
src/lib/v-remixicon.js

@@ -1,6 +1,7 @@
 import vRemixicon from 'v-remixicon';
 import {
   riHome5Line,
+  riArrowLeftRightLine,
   riFileUploadLine,
   riLightbulbLine,
   riSideBarLine,
@@ -84,6 +85,7 @@ import {
 
 export const icons = {
   riHome5Line,
+  riArrowLeftRightLine,
   riFileUploadLine,
   riLightbulbLine,
   riSideBarLine,

+ 7 - 0
src/locales/en/blocks.json

@@ -236,6 +236,13 @@
         "incScrollX": "Increment horizontal scroll",
         "incScrollY": "Increment vertical scroll"
       },
+      "switch-tab": {
+        "name": "Switch tab",
+        "description": "Switch between tab",
+        "matchPattern": "Match Patterns",
+        "url": "URL for the new tab",
+        "createIfNoMatch": "Create if there's no match"
+      },
       "new-tab": {
         "name": "New tab",
         "description": "",

+ 1 - 0
src/locales/en/common.json

@@ -7,6 +7,7 @@
     "block": "Block | Blocks",
     "docs": "Documentation",
     "search": "Search",
+    "example": "Example | Examples",
     "import": "Import",
     "export": "Export",
     "rename": "Rename",

+ 1 - 0
src/locales/en/newtab.json

@@ -147,6 +147,7 @@
       "stop-timeout": "Workflow is stopped because of timeout",
       "no-file-access": "Automa doesn't have access to the file",
       "no-workflow": "Can't find workflow with \"{workflowId}\" ID",
+      "no-match-tab": "Can't find a tab with \"{pattern}\" patterns",
       "element-not-found": "Can't find an element with \"{selector}\" selector.",
       "not-iframe": "Element with \"{selector}\" selector is not an Iframe element",
       "iframe-not-found": "Can't find an Iframe element with \"{selector}\" selector.",

+ 1 - 0
src/manifest.json

@@ -41,6 +41,7 @@
     "proxy",
     "alarms",
     "storage",
+    "debugger",
     "webNavigation",
     "unlimitedStorage",
     "<all_urls>"

+ 5 - 5
src/newtab/pages/logs/[id].vue

@@ -112,23 +112,23 @@ import LogsDataViewer from '@/components/newtab/logs/LogsDataViewer.vue';
 
 const logsType = {
   success: {
-    color: 'bg-green-200 dark:bg-green-400',
+    color: 'bg-green-200 dark:bg-green-300',
     icon: 'riCheckLine',
   },
   stop: {
-    color: 'bg-yellow-200 dark:bg-yellow-400',
+    color: 'bg-yellow-200 dark:bg-yellow-300',
     icon: 'riStopLine',
   },
   stopped: {
-    color: 'bg-yellow-200 dark:bg-yellow-400',
+    color: 'bg-yellow-200 dark:bg-yellow-300',
     icon: 'riStopLine',
   },
   error: {
-    color: 'bg-red-200 dark:bg-red-400',
+    color: 'bg-red-200 dark:bg-red-300',
     icon: 'riErrorWarningLine',
   },
   finish: {
-    color: 'bg-blue-200 dark:bg-blue-400',
+    color: 'bg-blue-200 dark:bg-blue-300',
     icon: 'riFlagLine',
   },
 };

+ 19 - 0
src/utils/shared.js

@@ -80,6 +80,25 @@ export const tasks = {
       updatePrevTab: false,
     },
   },
+  'switch-tab': {
+    name: 'Switch tab',
+    description: 'Switch active tab',
+    icon: 'riArrowLeftRightLine',
+    component: 'BlockBasic',
+    editComponent: 'EditSwitchTab',
+    category: 'browser',
+    inputs: 1,
+    outputs: 1,
+    allowedInputs: true,
+    maxConnection: 1,
+    refDataKeys: ['url', 'matchPattern'],
+    data: {
+      description: '',
+      url: '',
+      matchPattern: '',
+      createIfNoMatch: false,
+    },
+  },
   'new-window': {
     name: 'New window',
     description: 'Create a new window',