Ahmad Kholid 1 년 전
부모
커밋
0457860fea
6개의 변경된 파일87개의 추가작업 그리고 46개의 파일을 삭제
  1. 1 1
      package.json
  2. 31 25
      src/content/blocksHandler/handlerForms.js
  3. 0 19
      src/content/index.js
  4. 34 0
      src/content/synchronizedLock.js
  5. 17 1
      src/stores/workflow.js
  6. 4 0
      src/workflowEngine/utils/testConditions.js

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "automa",
-  "version": "1.28.16",
+  "version": "1.28.17",
   "description": "An extension for automating your browser by connecting blocks",
   "repository": {
     "type": "git",

+ 31 - 25
src/content/blocksHandler/handlerForms.js

@@ -1,6 +1,7 @@
-import { sendMessage } from '@/utils/message';
 import handleFormElement from '@/utils/handleFormElement';
+import { sendMessage } from '@/utils/message';
 import handleSelector, { markElement } from '../handleSelector';
+import synchronizedLock from '../synchronizedLock';
 
 async function forms(block) {
   const { data } = block;
@@ -24,38 +25,43 @@ async function forms(block) {
 
   async function typeText(element) {
     if (block.debugMode && data.type === 'text-field') {
+      // get lock
+      await synchronizedLock.getLock();
       element.focus?.();
 
-      if (data.clearValue) {
-        const backspaceCommands = new Array(element.value?.length ?? 0).fill({
-          type: 'rawKeyDown',
-          unmodifiedText: 'Delete',
-          text: 'Delete',
-          windowsVirtualKeyCode: 46,
-        });
+      try {
+        if (data.clearValue) {
+          const backspaceCommands = new Array(element.value?.length ?? 0).fill({
+            type: 'rawKeyDown',
+            unmodifiedText: 'Delete',
+            text: 'Delete',
+            windowsVirtualKeyCode: 46,
+          });
+
+          await sendMessage(
+            'debugger:type',
+            { commands: backspaceCommands, tabId: block.activeTabId, delay: 0 },
+            'background'
+          );
+        }
 
+        const commands = data.value.split('').map((char) => ({
+          type: 'keyDown',
+          text: char === '\n' ? '\r' : char,
+        }));
+        const typeDelay = +block.data.delay;
         await sendMessage(
           'debugger:type',
-          { commands: backspaceCommands, tabId: block.activeTabId, delay: 0 },
+          {
+            commands,
+            tabId: block.activeTabId,
+            delay: Number.isNaN(typeDelay) ? 0 : typeDelay,
+          },
           'background'
         );
+      } finally {
+        synchronizedLock.releaseLock();
       }
-
-      const commands = data.value.split('').map((char) => ({
-        type: 'keyDown',
-        text: char === '\n' ? '\r' : char,
-      }));
-      const typeDelay = +block.data.delay;
-      await sendMessage(
-        'debugger:type',
-        {
-          commands,
-          tabId: block.activeTabId,
-          delay: Number.isNaN(typeDelay) ? 0 : typeDelay,
-        },
-        'background'
-      );
-
       return;
     }
 

+ 0 - 19
src/content/index.js

@@ -240,19 +240,9 @@ async function messageListener({ data, source }) {
 
   automa('content');
 
-  let locked = false;
-  const queue = [];
-
   browser.runtime.onMessage.addListener(async (data) => {
     const asyncExecuteBlock = async (block) => {
-      if (locked) {
-        return new Promise((resolve, reject) => {
-          queue.push([block, resolve, reject]);
-        });
-      }
-
       try {
-        locked = true;
         const res = await executeBlock(block);
         return res;
       } catch (error) {
@@ -275,20 +265,11 @@ async function messageListener({ data, source }) {
 
         await blocksHandler().loopData(loopBlock);
         return executeBlock(block);
-      } finally {
-        locked = false;
       }
     };
 
     if (data.isBlock) {
       const res = await asyncExecuteBlock(data);
-      while (queue.length) {
-        const [block, resolve, reject] = queue.shift();
-        requestAnimationFrame(() => {
-          asyncExecuteBlock(block).then(resolve).catch(reject);
-        });
-      }
-
       return res;
     }
 

+ 34 - 0
src/content/synchronizedLock.js

@@ -0,0 +1,34 @@
+class SynchronizedLock {
+  constructor() {
+    this.lock = false;
+    this.queue = [];
+  }
+
+  async getLock(timeout = 10000) {
+    while (this.lock) {
+      await new Promise((resolve) => {
+        this.queue.push(resolve);
+        setTimeout(() => {
+          const index = this.queue.indexOf(resolve);
+          if (index !== -1) {
+            this.queue.splice(index, 1);
+            console.warn('SynchronizedLock timeout');
+            resolve();
+          }
+        }, timeout);
+      });
+    }
+
+    this.lock = true;
+  }
+
+  releaseLock() {
+    this.lock = false;
+    const resolve = this.queue.shift();
+    if (resolve) resolve();
+  }
+}
+
+const synchronizedLock = new SynchronizedLock();
+
+export default synchronizedLock;

+ 17 - 1
src/stores/workflow.js

@@ -7,7 +7,10 @@ import dayjs from 'dayjs';
 import { fetchApi } from '@/utils/api';
 import { tasks } from '@/utils/shared';
 import firstWorkflows from '@/utils/firstWorkflows';
-import { cleanWorkflowTriggers } from '@/utils/workflowTrigger';
+import {
+  cleanWorkflowTriggers,
+  registerWorkflowTrigger,
+} from '@/utils/workflowTrigger';
 import { useUserStore } from './user';
 
 const defaultWorkflow = (data = null, options = {}) => {
@@ -180,6 +183,19 @@ export const useWorkflowStore = defineStore('workflow', {
 
         this.workflows[workflowId].updatedAt = Date.now();
         updatedWorkflows[workflowId] = this.workflows[workflowId];
+
+        if (!('isDisabled' in data)) return;
+
+        if (data.isDisabled) {
+          cleanWorkflowTriggers(workflowId);
+        } else {
+          const triggerBlock = this.workflows[workflowId].drawflow.nodes?.find(
+            (node) => node.label === 'trigger'
+          );
+          if (triggerBlock) {
+            registerWorkflowTrigger(id, triggerBlock);
+          }
+        }
       };
 
       if (isFunction) {

+ 4 - 0
src/workflowEngine/utils/testConditions.js

@@ -3,6 +3,7 @@ import objectPath from 'object-path';
 import { parseJSON } from '@/utils/helper';
 import { conditionBuilder } from '@/utils/shared';
 import renderString from '../templating/renderString';
+import { keyParser } from '../templating/mustacheReplacer';
 
 const isBoolStr = (str) => {
   if (str === 'true') return true;
@@ -59,6 +60,9 @@ export default async function (conditionsArr, workflowData) {
         dataPath = dataPath.slice(2, -2).trim();
       }
 
+      const parsedPath = keyParser(dataPath, workflowData.refData);
+      dataPath = `${parsedPath.dataKey}.${parsedPath.path}`;
+
       return objectPath.has(workflowData.refData, dataPath);
     }