瀏覽代碼

feat: add delay and get-text handler

Ahmad Kholid 3 年之前
父節點
當前提交
74f30ded2d

+ 31 - 1
src/background/blocks-handler.js

@@ -57,7 +57,7 @@ export function eventClick(block) {
 
     this._connectedTab.postMessage(block);
     this._listenTabMessage(
-      'event-click',
+      block.name,
       () => {
         resolve({
           nextBlockId: getBlockConnection(block),
@@ -68,3 +68,33 @@ export function eventClick(block) {
     );
   });
 }
+
+export function getText(block) {
+  return new Promise((resolve) => {
+    if (!this._connectedTab) return;
+
+    this._connectedTab.postMessage(block);
+    this._listenTabMessage(
+      block.name,
+      (data) => {
+        console.log('hha', data);
+        resolve({
+          nextBlockId: getBlockConnection(block),
+          data: '',
+        });
+      },
+      { once: true }
+    );
+  });
+}
+
+export function delay(block) {
+  return new Promise((resolve) => {
+    setTimeout(() => {
+      resolve({
+        nextBlockId: getBlockConnection(block),
+        data: '',
+      });
+    }, block.data.time);
+  });
+}

+ 22 - 17
src/background/workflow-engine.js

@@ -12,6 +12,15 @@ function tabMessageListenerHandler({ type, data }) {
     if (listener.once) delete this.tabMessageListeners[type];
   }
 }
+function tabRemovedListener(tabId) {
+  if (tabId !== this.tabId) return;
+
+  this.connectedTab?.onMessage.removeListener(this.tabMessageListenerHandler);
+  this.connectedTab?.disconnect();
+
+  delete this.connectedTab;
+  delete this.tabId;
+}
 
 class WorkflowEngine {
   constructor(workflow) {
@@ -20,8 +29,10 @@ class WorkflowEngine {
     this.blocksArr = [];
     this.data = [];
     this.isDestroyed = false;
+    this.logs = [];
 
     this.tabMessageListeners = {};
+    this.tabRemovedListener = tabRemovedListener.bind(this);
     this.tabMessageListenerHandler = tabMessageListenerHandler.bind(this);
   }
 
@@ -42,6 +53,8 @@ class WorkflowEngine {
       return;
     }
 
+    browser.tabs.onRemoved.addListener(this.tabRemovedListener);
+
     this.blocks = blocks;
     this.blocksArr = blocksArr;
 
@@ -49,13 +62,20 @@ class WorkflowEngine {
   }
 
   destroy() {
-    // Add 'destroyed' log
+    // save log
+    browser.tabs.onRemoved.removeListener(this.tabRemovedListener);
 
     this.isDestroyed = true;
   }
 
   _blockHandler(block, prevBlockData) {
-    if (this.isDestroyed) return;
+    if (this.isDestroyed) {
+      console.log(
+        '%cDestroyed',
+        'color: red; font-size: 24px; font-weight: bold'
+      );
+      return;
+    }
 
     console.log(`${block.name}(${toCamelCase(block.name)}):`, block);
     const handler = blocksHandler[toCamelCase(block?.name)];
@@ -79,21 +99,6 @@ class WorkflowEngine {
   }
 
   _connectTab(tabId) {
-    const tabRemovedListener = (id) => {
-      if (id !== tabId) return;
-
-      this.destroy();
-      this.connectedTab.onMessage.removeListener(
-        this.tabMessageListenerHandler
-      );
-      this.connectedTab.disconnect();
-
-      delete this.connectedTab;
-      delete this.tabId;
-
-      browser.tabs.onRemoved.removeListener(tabRemovedListener);
-    };
-
     const connectedTab = browser.tabs.connect(tabId, {
       name: `${this.workflow.id}--${this.workflow.name.slice(0, 10)}`,
     });

+ 5 - 5
src/components/newtab/workflow/WorkflowDetailsCard.vue

@@ -39,8 +39,8 @@
       <v-remixicon name="riSaveLine" class="mr-2 -ml-1" />
       Save
     </ui-button>
-    <ui-button icon title="Data columns" @click="$emit('showDataColumns')">
-      <v-remixicon name="riKey2Line" />
+    <ui-button icon title="Execute" @click="$emit('execute')">
+      <v-remixicon name="riPlayLine" />
     </ui-button>
     <ui-popover>
       <template #trigger>
@@ -49,9 +49,9 @@
         </ui-button>
       </template>
       <ui-list class="w-36">
-        <ui-list-item class="cursor-pointer" @click="$emit('execute')">
-          <v-remixicon name="riPlayLine" class="mr-2 -ml-1" />
-          <span>Execute</span>
+        <ui-list-item class="cursor-pointer" @click="$emit('showDataColumns')">
+          <v-remixicon name="riKey2Line" class="mr-2 -ml-1" />
+          <span>Data columns</span>
         </ui-list-item>
         <ui-list-item
           v-close-popover

+ 42 - 7
src/components/newtab/workflow/edit/EditGetText.vue

@@ -1,11 +1,30 @@
 <template>
   <edit-interaction-base v-bind="{ data }" @change="updateData">
-    <ui-input
-      :model-value="data.regex"
-      placeholder="Regex"
-      class="mt-2 w-full"
-      @change="updateData"
-    />
+    <div class="flex rounded-lg bg-input px-4 items-center transition mt-2">
+      <span>/</span>
+      <input
+        :value="data.regex"
+        placeholder="Regex"
+        class="w-11/12 bg-transparent p-2 focus:ring-0"
+        @change="updateData({ regex: $event.target.value })"
+      />
+      <ui-popover>
+        <template #trigger>
+          <button>/{{ regexExp.join('') }}</button>
+        </template>
+        <p class="mb-2 text-gray-600 dark:text-gray-200">Expression flags</p>
+        <div class="space-y-1">
+          <div v-for="item in exps" :key="item.id">
+            <ui-checkbox
+              :model-value="regexExp.includes(item.id)"
+              @change="handleExpCheckbox(item.id, $event)"
+            >
+              {{ item.name }}
+            </ui-checkbox>
+          </div>
+        </div>
+      </ui-popover>
+    </div>
     <div class="flex items-center mt-3">
       <ui-select
         :model-value="data.dataColumn"
@@ -32,7 +51,7 @@
   </edit-interaction-base>
 </template>
 <script setup>
-import { inject } from 'vue';
+import { inject, ref } from 'vue';
 import EditInteractionBase from './EditInteractionBase.vue';
 
 const props = defineProps({
@@ -44,8 +63,24 @@ const props = defineProps({
 const emit = defineEmits(['update:data']);
 
 const workflow = inject('workflow');
+const regexExp = ref(props.data.regexExp);
+
+const exps = [
+  { id: 'g', name: 'global' },
+  { id: 'i', name: 'ignore case' },
+  { id: 'm', name: 'multiline' },
+];
 
 function updateData(value) {
   emit('update:data', { ...props.data, ...value });
 }
+function handleExpCheckbox(id, value) {
+  if (value) {
+    regexExp.value.push(id);
+  } else {
+    regexExp.value.splice(regexExp.value.indexOf(id), 1);
+  }
+
+  updateData({ regexExp: regexExp.value });
+}
 </script>

+ 21 - 3
src/content/blocks-handler.js

@@ -12,11 +12,29 @@ function handleElement(data, callback) {
   }
 }
 
-export function eventClick({ data }, port) {
+export function eventClick({ data, name }, port) {
   handleElement(data, (element) => {
-    console.log(element);
     element.click();
   });
 
-  port.postMessage({ type: 'event-click' });
+  port.postMessage({ type: name });
+}
+
+export function getText({ data, name }, port) {
+  let regex;
+  let textResult = '';
+
+  if (data.regex) {
+    regex = new RegExp(data.regex, data.regexExp.join(''));
+  }
+
+  handleElement(data, (element) => {
+    let text = element.innerText;
+
+    if (regex) text = text.match(regex).join(' ');
+
+    textResult += `${text} `;
+  });
+
+  port.postMessage({ type: name, data: textResult });
 }

+ 1 - 0
src/utils/shared.js

@@ -59,6 +59,7 @@ export const tasks = {
       selector: '',
       multiple: false,
       regex: '',
+      regexExp: ['g'],
       dataColumn: '',
     },
   },