فهرست منبع

feat: support XPath in loop data selector

Ahmad Kholid 3 سال پیش
والد
کامیت
467dfcd6e9

+ 1 - 0
src/background/workflowEngine/blocksHandler/handlerLoopData.js

@@ -41,6 +41,7 @@ async function loopData({ data, id, outputs }, { refData }) {
             max: data.maxLoop,
             type: 'loop-elements',
             selector: data.elementSelector,
+            frameSelector: this.frameSelector,
           });
 
           return elements;

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

@@ -49,7 +49,7 @@
         :model-value="data.elementSelector"
         :label="t('workflow.blocks.base.selector')"
         autocomplete="off"
-        placeholder=".selector"
+        placeholder="CSS Selector or XPath"
         class="w-full"
         @change="updateData({ elementSelector: $event })"
       />

+ 14 - 11
src/content/handleSelector.js

@@ -40,6 +40,16 @@ export function queryElements(data, documentCtx = document) {
   });
 }
 
+export function getDocumentCtx(frameSelector) {
+  let documentCtx = document;
+
+  if (frameSelector) {
+    documentCtx = document.querySelector(frameSelector)?.contentDocument;
+  }
+
+  return documentCtx;
+}
+
 export default async function (
   { data, id, frameSelector, debugMode },
   { onSelected, onError, onSuccess }
@@ -49,18 +59,11 @@ export default async function (
     return null;
   }
 
-  let documentCtx = document;
+  const documentCtx = getDocumentCtx(frameSelector);
+  if (!documentCtx) {
+    if (onError) onError(new Error('iframe-not-found'));
 
-  if (frameSelector) {
-    const iframeCtx = document.querySelector(frameSelector)?.contentDocument;
-
-    if (!iframeCtx) {
-      if (onError) onError(new Error('iframe-not-found'));
-
-      return null;
-    }
-
-    documentCtx = iframeCtx;
+    return null;
   }
 
   try {

+ 10 - 1
src/content/index.js

@@ -2,6 +2,7 @@ import browser from 'webextension-polyfill';
 import { nanoid } from 'nanoid';
 import { toCamelCase } from '@/utils/helper';
 import FindElement from '@/utils/FindElement';
+import { getDocumentCtx } from './handleSelector';
 import executedBlock from './executedBlock';
 import blocksHandler from './blocksHandler';
 
@@ -88,7 +89,15 @@ function handleConditionBuilder({ data, type }) {
         case 'loop-elements': {
           const selectors = [];
           const attrId = nanoid(5);
-          const elements = document.body.querySelectorAll(data.selector);
+
+          const documentCtx = getDocumentCtx(data.frameSelector);
+          const selectorType = data.selector.startsWith('/')
+            ? 'xpath'
+            : 'cssSelector';
+          const elements = FindElement[selectorType](
+            { selector: data.selector, multiple: true },
+            documentCtx
+          );
 
           elements.forEach((el, index) => {
             if (data.max > 0 && selectors.length - 1 > data.max) return;