Ahmad Kholid 1 year ago
parent
commit
e9810b3325

+ 1 - 1
package.json

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

+ 35 - 0
src/background/index.js

@@ -253,4 +253,39 @@ if (!isMV2) {
   sandboxIframe.id = 'sandbox';
 
   document.body.appendChild(sandboxIframe);
+
+  window.addEventListener('message', async ({ data }) => {
+    if (data?.type !== 'automa-fetch') return;
+
+    const sendResponse = (result) => {
+      sandboxIframe.contentWindow.postMessage(
+        {
+          type: 'fetchResponse',
+          data: result,
+          id: data.data.id,
+        },
+        '*'
+      );
+    };
+
+    const { type, resource } = data.data;
+    try {
+      const response = await fetch(resource.url, resource);
+      if (!response.ok) throw new Error(response.statusText);
+
+      let result = null;
+
+      if (type === 'base64') {
+        const blob = await response.blob();
+        const base64 = await readFileAsBase64(blob);
+
+        result = base64;
+      } else {
+        result = await response[type]();
+      }
+      sendResponse({ isError: false, result });
+    } catch (error) {
+      sendResponse({ isError: true, result: error.message });
+    }
+  });
 }

+ 1 - 1
src/components/newtab/workflow/edit/EditJavascriptCode.vue

@@ -61,7 +61,7 @@
         Run before page loaded
       </ui-checkbox>
     </template>
-    <ui-modal v-model="state.showCodeModal" content-class="max-w-4xl">
+    <ui-modal v-model="state.showCodeModal" content-class="w-11\/12">
       <template #header>
         <ui-tabs v-model="state.activeTab" class="border-none">
           <ui-tab value="code">

+ 10 - 4
src/content/handleSelector.js

@@ -10,13 +10,18 @@ export function markElement(el, { id, data }) {
 }
 
 export function getDocumentCtx(frameSelector) {
+  if (!frameSelector) return document;
+
   let documentCtx = document;
 
-  if (frameSelector) {
-    const type = isXPath(frameSelector) ? 'xpath' : 'cssSelector';
-    const element = FindElement[type]({ selector: frameSelector });
+  const iframeSelectors = frameSelector.split('|>');
+  const type = isXPath(frameSelector) ? 'xpath' : 'cssSelector';
+  iframeSelectors.forEach((selector) => {
+    if (!documentCtx) return;
+
+    const element = FindElement[type]({ selector }, documentCtx);
     documentCtx = element?.contentDocument;
-  }
+  });
 
   return documentCtx;
 }
@@ -62,6 +67,7 @@ export default async function (
   }
 
   const documentCtx = getDocumentCtx(frameSelector);
+
   if (!documentCtx) {
     if (onError) onError(new Error('iframe-not-found'));
 

+ 19 - 8
src/content/index.js

@@ -5,7 +5,10 @@ import findSelector from '@/lib/findSelector';
 import { sendMessage } from '@/utils/message';
 import automa from '@business';
 import { toCamelCase, isXPath } from '@/utils/helper';
-import handleSelector, { queryElements } from './handleSelector';
+import handleSelector, {
+  queryElements,
+  getDocumentCtx,
+} from './handleSelector';
 import blocksHandler from './blocksHandler';
 import showExecutedBlock from './showExecutedBlock';
 import shortcutListener from './services/shortcutListener';
@@ -49,19 +52,27 @@ function messageToFrame(frameElement, blockData) {
 async function executeBlock(data) {
   const removeExecutedBlock = showExecutedBlock(data, data.executedBlockOnWeb);
   if (data.data?.selector?.includes('|>')) {
-    const [frameSelector, selector] = data.data.selector.split(/\|>(.+)/);
+    const selectorsArr = data.data.selector.split('|>');
+    const selector = selectorsArr.pop();
+    const frameSelector = selectorsArr.join('|>');
+
+    const framElSelector = selectorsArr.pop();
 
     let findBy = data?.data?.findBy;
     if (!findBy) {
       findBy = isXPath(frameSelector) ? 'xpath' : 'cssSelector';
     }
 
-    const frameElement = await queryElements({
-      findBy,
-      multiple: false,
-      waitForSelector: 5000,
-      selector: frameSelector,
-    });
+    const documentCtx = getDocumentCtx(selectorsArr.join('|>'));
+    const frameElement = await queryElements(
+      {
+        findBy,
+        multiple: false,
+        waitForSelector: 5000,
+        selector: framElSelector,
+      },
+      documentCtx
+    );
     const frameError = (message) => {
       const error = new Error(message);
       error.data = { selector: frameSelector };

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

@@ -1239,12 +1239,15 @@ function onDragoverEditor({ target }) {
 }
 function onDropInEditor({ dataTransfer, clientX, clientY, target }) {
   const savedBlocks = parseJSON(dataTransfer.getData('savedBlocks'), null);
+
+  const editorRect = editor.value.viewportRef.value.getBoundingClientRect();
+  const position = editor.value.project({
+    y: clientY - editorRect.top,
+    x: clientX - editorRect.left,
+  });
+
   if (savedBlocks && !isPackage) {
     if (savedBlocks.settings.asBlock) {
-      const position = editor.value.project({
-        x: clientX - 360,
-        y: clientY - 18,
-      });
       editor.value.addNodes([
         {
           position,
@@ -1285,7 +1288,6 @@ function onDropInEditor({ dataTransfer, clientX, clientY, target }) {
     return;
   }
 
-  const position = editor.value.project({ x: clientX - 360, y: clientY - 18 });
   const nodeId = nanoid();
   const newNode = {
     position,

+ 5 - 4
src/workflowEngine/blocksHandler/handlerHandleDownload.js

@@ -144,15 +144,16 @@ async function handleDownload({ data, id: blockId }) {
         return;
       }
 
-      if (downloadId !== id) return;
+      if (downloadId !== id || !state) return;
 
       if (filename) currentFilename = filename.current;
 
-      if (state && state.current === 'complete') {
+      const DOWNLOAD_STATE = ['complete', 'interrupted'];
+      if (DOWNLOAD_STATE.includes(state.current)) {
         resolvePromise(id);
       } else {
-        browser.downloads.search({ id }).then(([download]) => {
-          if (!download || !download.endTime) return;
+        browser.downloads.search({ id: downloadId }).then(([download]) => {
+          if (!download || !DOWNLOAD_STATE.includes(download.state)) return;
 
           resolvePromise(id);
         });