diff --git a/package.json b/package.json index 4cbd678c..21ba612c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "automa", - "version": "1.28.19", + "version": "1.28.21", "description": "An extension for automating your browser by connecting blocks", "repository": { "type": "git", diff --git a/src/content/blocksHandler/handlerElementScroll.js b/src/content/blocksHandler/handlerElementScroll.js index d24e6df1..e932502b 100644 --- a/src/content/blocksHandler/handlerElementScroll.js +++ b/src/content/blocksHandler/handlerElementScroll.js @@ -1,5 +1,54 @@ import handleSelector from '../handleSelector'; +function isElScrollable(element) { + const excludedTags = ['SCRIPT', 'STYLE', 'SVG', 'HEAD']; + + const isOverflow = /scroll|auto/.test(getComputedStyle(element).overflow); + const isScrollable = + element.scrollHeight > element.clientHeight || + element.scrollWidth > element.clientWidth; + const isExcluded = + element.tagName.includes('-') || excludedTags.includes(element.tagName); + + return isOverflow && isScrollable && !isExcluded; +} + +function findScrollableElement( + element = document.documentElement, + dir = 'down', + maxDepth = 5 +) { + if (maxDepth === 0) return null; + + const isScrollable = isElScrollable(element); + if (isScrollable) return element; + + if (dir === 'up') { + const parentEl = element.parentElement; + if (!parentEl) return null; + + const scrollableElement = findScrollableElement( + parentEl, + dir, + maxDepth - 1 + ); + if (scrollableElement) return scrollableElement; + } else { + for (let index = 0; index < element.childElementCount; index += 1) { + const currentChild = element.children.item(index); + const scrollableElement = findScrollableElement( + currentChild, + dir, + maxDepth - 1 + ); + + if (scrollableElement) return scrollableElement; + } + } + + return null; +} + function elementScroll(block) { function incScrollPos(element, data, vertical = true) { let currentPos = vertical ? element.scrollTop : element.scrollLeft; @@ -22,7 +71,12 @@ function elementScroll(block) { if (data.scrollIntoView) { element.scrollIntoView({ behavior, block: 'center' }); } else { - element.scroll({ + const scrollableEl = + findScrollableElement(element, 'up', 3) || + findScrollableElement(element, 'down', 3) || + element; + + scrollableEl.scroll({ behavior, top: data.incY ? incScrollPos(element, data) : data.scrollY, left: data.incX ? incScrollPos(element, data, false) : data.scrollX, diff --git a/src/content/blocksHandler/handlerJavascriptCode.js b/src/content/blocksHandler/handlerJavascriptCode.js index c5b10996..48f630af 100644 --- a/src/content/blocksHandler/handlerJavascriptCode.js +++ b/src/content/blocksHandler/handlerJavascriptCode.js @@ -1,4 +1,5 @@ import { jsContentHandler } from '@/workflowEngine/utils/javascriptBlockUtil'; +import { getDocumentCtx } from '../handleSelector'; function javascriptCode({ data, isPreloadScripts, frameSelector }) { if (!isPreloadScripts && Array.isArray(data)) @@ -8,7 +9,7 @@ function javascriptCode({ data, isPreloadScripts, frameSelector }) { let $documentCtx = document; if (frameSelector) { - const iframeCtx = document.querySelector(frameSelector)?.contentDocument; + const iframeCtx = getDocumentCtx(frameSelector); if (!iframeCtx) return Promise.resolve({ success: false }); $documentCtx = iframeCtx; diff --git a/src/workflowEngine/WorkflowEngine.js b/src/workflowEngine/WorkflowEngine.js index a91da958..cfb9dbb3 100644 --- a/src/workflowEngine/WorkflowEngine.js +++ b/src/workflowEngine/WorkflowEngine.js @@ -491,35 +491,17 @@ class WorkflowEngine { 'rw', dbStorage.tablesItems, dbStorage.tablesData, - dbStorage.variables, async () => { - if (tableId) { - await dbStorage.tablesItems.update(tableId, { - modifiedAt: Date.now(), - rowsCount: table.length, - }); - await dbStorage.tablesData.where('tableId').equals(tableId).modify({ - items: table, - columnsIndex: this.columns, - }); - } + if (!tableId) return; - for (const key in variables) { - if (key.startsWith('$$')) { - const varName = key.slice(2); - const varValue = variables[key]; - - const variable = - (await dbStorage.variables - .where('name') - .equals(varName) - .first()) || {}; - variable.name = varName; - variable.value = varValue; - - await dbStorage.variables.put(variable); - } - } + await dbStorage.tablesItems.update(tableId, { + modifiedAt: Date.now(), + rowsCount: table.length, + }); + await dbStorage.tablesData.where('tableId').equals(tableId).modify({ + items: table, + columnsIndex: this.columns, + }); } ); diff --git a/src/workflowEngine/WorkflowWorker.js b/src/workflowEngine/WorkflowWorker.js index 18d24780..0268eeae 100644 --- a/src/workflowEngine/WorkflowWorker.js +++ b/src/workflowEngine/WorkflowWorker.js @@ -7,6 +7,7 @@ import { parseJSON, isObject, } from '@/utils/helper'; +import dbStorage from '@/db/storage'; import templating from './templating'; import renderString from './templating/renderString'; import { convertData, waitTabLoaded } from './helper'; @@ -110,6 +111,7 @@ class WorkflowWorker { } setVariable(name, value) { + let variableName = name; const vars = this.engine.referenceData.variables; if (name.startsWith('$push:')) { @@ -119,9 +121,18 @@ class WorkflowWorker { else if (!Array.isArray(vars[varName])) vars[varName] = [vars[varName]]; vars[varName].push(value); + variableName = varName; + } else { + vars[name] = value; + } + + if (variableName.startsWith('$$')) { + dbStorage.variables.put({ + value, + name: variableName.slice(2), + }); } - vars[name] = value; this.engine.addRefDataSnapshot('variables'); } diff --git a/src/workflowEngine/utils/javascriptBlockUtil.js b/src/workflowEngine/utils/javascriptBlockUtil.js index 7f8936ce..f747f03b 100644 --- a/src/workflowEngine/utils/javascriptBlockUtil.js +++ b/src/workflowEngine/utils/javascriptBlockUtil.js @@ -1,3 +1,5 @@ +import { getDocumentCtx } from '@/content/handleSelector'; + export function automaFetchClient(id, { type, resource }) { return new Promise((resolve, reject) => { const validType = ['text', 'json', 'base64']; @@ -71,10 +73,7 @@ export function jsContentHandler($blockData, $preloadScripts, $automaScript) { let $documentCtx = document; if ($blockData.frameSelector) { - const iframeCtx = document.querySelector( - $blockData.frameSelector - )?.contentDocument; - + const iframeCtx = getDocumentCtx($blockData.frameSelector); if (!iframeCtx) { reject(new Error('iframe-not-found')); return;