1
0
Ahmad Kholid 1 жил өмнө
parent
commit
c12f39524c

+ 1 - 1
package.json

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

+ 2 - 3
src/components/newtab/workflow/edit/EditPressKey.vue

@@ -76,12 +76,11 @@
       @change="updateData({ keysToPress: $event })"
     />
     <ui-input
-      :model-value="Math.min(data.pressTime || 0, 0)"
+      :model-value="data.pressTime || 0"
       :label="t('workflow.blocks.press-key.press-time')"
-      type="number"
       class="w-full mt-2"
       :placeholder="t('common.millisecond')"
-      @change="updateData({ pressTime: +$event })"
+      @change="updateData({ pressTime: $event })"
     />
   </div>
 </template>

+ 8 - 1
src/components/newtab/workflow/editor/EditorLocalActions.vue

@@ -131,7 +131,7 @@
         :class="[
           { 'cursor-default': isDataChanged },
           workflow.testingMode
-            ? 'bg-primary bg-primary bg-opacity-20 text-primary'
+            ? 'bg-primary bg-opacity-20 text-primary'
             : 'hoverable',
         ]"
         class="rounded-lg p-2"
@@ -333,6 +333,7 @@ import { useToast } from 'vue-toastification';
 import browser from 'webextension-polyfill';
 import { fetchApi } from '@/utils/api';
 import { useUserStore } from '@/stores/user';
+import { useStore } from '@/stores/main';
 import { useWorkflowStore } from '@/stores/workflow';
 import { useTeamWorkflowStore } from '@/stores/teamWorkflow';
 import { useSharedWorkflowStore } from '@/stores/sharedWorkflow';
@@ -381,6 +382,7 @@ const { t } = useI18n();
 const toast = useToast();
 const router = useRouter();
 const dialog = useDialog();
+const mainStore = useStore();
 const userStore = useUserStore();
 const packageStore = usePackageStore();
 const workflowStore = useWorkflowStore();
@@ -468,6 +470,11 @@ function updateWorkflowDescription(value) {
   state.showEditDescription = false;
 }
 function executeCurrWorkflow() {
+  if (mainStore.settings.editor.saveWhenExecute && props.isDataChanged) {
+    // eslint-disable-next-line no-use-before-define
+    saveWorkflow();
+  }
+
   executeWorkflow({
     ...props.workflow,
     isTesting: props.isDataChanged,

+ 1 - 3
src/content/blocksHandler/handlerElementScroll.js

@@ -2,15 +2,13 @@ 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;
+  return isScrollable && !isExcluded;
 }
 
 function findScrollableElement(

+ 7 - 5
src/content/blocksHandler/handlerPressKey.js

@@ -60,11 +60,13 @@ async function pressKeyWithJs({ element, keys, pressTime }) {
       const isTextField = textFieldTags.includes(element.tagName);
 
       if (isEditable || isTextField) {
-        const isDigit = /^[0-9]$/.test(key);
         const contentKey = isEditable ? 'textContent' : 'value';
-
-        if (isLetter || isDigit) {
-          element[contentKey] += key;
+        if (isLetter || (keyDefinitions[key] && key.length === 1)) {
+          if (isEditable && document.execCommand) {
+            document.execCommand('insertText', false, key);
+          } else {
+            element[contentKey] += key;
+          }
 
           return;
         }
@@ -174,7 +176,7 @@ async function pressKey({ data, debugMode, activeTabId }) {
     element,
     activeTabId,
     actionType: data.action,
-    pressTime: Number.isNaN(+data.pressTime) ? 0 : +data.pressTime,
+    pressTime: Number.isNaN(+data.pressTime) ? 0 : Math.abs(+data.pressTime),
   });
 
   return '';

+ 4 - 0
src/locales/en/newtab.json

@@ -123,6 +123,10 @@
       "snapGrid": {
         "title": "Snap to the grid",
         "description": "Snap to the grid when moving a block"
+      },
+      "saveWhenExecute": {
+        "title": "Auto-save when execute workflow",
+        "description": "Workflow changes will be saved when executing the workflow"
       }
     },
     "deleteLog": {

+ 4 - 1
src/newtab/pages/settings/SettingsBackup.vue

@@ -416,7 +416,10 @@ async function restoreWorkflows() {
     };
 
     reader.onload = ({ target }) => {
-      const payload = parseJSON(window.decodeURIComponent(target.result), null);
+      let payload = parseJSON(target.result, null);
+      if (!payload)
+        payload = parseJSON(window.decodeURIComponent(target.result), null);
+
       if (!payload) return;
 
       const storageTables = parseJSON(payload.storageTables, null);

+ 11 - 0
src/newtab/pages/settings/SettingsEditor.vue

@@ -54,6 +54,17 @@
           />
         </div>
       </transition-expand>
+      <ui-list-item small>
+        <ui-switch v-model="settings.saveWhenExecute" />
+        <div class="ml-4 flex-1">
+          <p class="leading-tight">
+            {{ t('settings.editor.saveWhenExecute.title') }}
+          </p>
+          <p class="text-sm leading-tight text-gray-600 dark:text-gray-200">
+            {{ t('settings.editor.saveWhenExecute.description') }}
+          </p>
+        </div>
+      </ui-list-item>
     </ui-list>
   </div>
 </template>

+ 8 - 1
src/newtab/pages/workflows/[id].vue

@@ -296,6 +296,7 @@ import {
   computed,
   onMounted,
   shallowRef,
+  onDeactivated,
   onBeforeUnmount,
 } from 'vue';
 import cloneDeep from 'lodash.clonedeep';
@@ -1529,7 +1530,7 @@ function checkWorkflowUpdate() {
 /* eslint-disable consistent-return */
 function onBeforeLeave() {
   // disselect node before leave
-  const selectedNodes = editor.value.getSelectedNodes.value;
+  const selectedNodes = editor.value?.getSelectedNodes?.value;
   selectedNodes?.forEach((node) => {
     node.selected = false;
   });
@@ -1579,6 +1580,12 @@ watch(
   }
 );
 
+onDeactivated(() => {
+  const selectedNodes = editor.value?.getSelectedNodes?.value;
+  selectedNodes?.forEach((node) => {
+    node.selected = false;
+  });
+});
 onBeforeRouteLeave(onBeforeLeave);
 onMounted(() => {
   if (!workflow.value) {

+ 1 - 0
src/stores/main.js

@@ -25,6 +25,7 @@ export const useStore = defineStore('main', {
         arrow: true,
         snapToGrid: false,
         lineType: 'default',
+        saveWhenExecute: false,
         snapGrid: { 0: 15, 1: 15 },
       },
     },

+ 3 - 2
src/stores/workflow.js

@@ -282,8 +282,9 @@ export const useWorkflowStore = defineStore('workflow', {
       const { pinnedWorkflows } = await browser.storage.local.get(
         'pinnedWorkflows'
       );
-      const pinnedWorkflowIndex =
-        pinnedWorkflows && pinnedWorkflows.indexOf(id);
+      const pinnedWorkflowIndex = pinnedWorkflows
+        ? pinnedWorkflows.indexOf(id)
+        : -1;
       if (pinnedWorkflowIndex !== -1) {
         pinnedWorkflows.splice(pinnedWorkflowIndex, 1);
         await browser.storage.local.set({ pinnedWorkflows });

+ 2 - 2
src/utils/shared.js

@@ -1047,12 +1047,12 @@ export const tasks = {
     outputs: 1,
     allowedInputs: true,
     maxConnection: 1,
-    refDataKeys: ['selector', 'keys', 'keysToPress'],
+    refDataKeys: ['selector', 'keys', 'keysToPress', 'pressTime'],
     data: {
       disableBlock: false,
       keys: '',
       selector: '',
-      pressTime: 0,
+      pressTime: '0',
       description: '',
       keysToPress: '',
       action: 'press-key',

+ 0 - 1
src/workflowEngine/blocksHandler/handlerDelay.js

@@ -1,7 +1,6 @@
 function delay(block) {
   return new Promise((resolve) => {
     const delayTime = +block.data.time || 500;
-    console.log(delayTime, 'huh', block);
     setTimeout(() => {
       resolve({
         data: '',

+ 25 - 2
src/workflowEngine/blocksHandler/handlerParameterPrompt.js

@@ -1,6 +1,7 @@
 import { nanoid } from 'nanoid/non-secure';
 import browser from 'webextension-polyfill';
 import { sleep } from '@/utils/helper';
+import renderString from '../templating/renderString';
 
 function getInputtedParams(promptId, ms = 10000) {
   return new Promise((resolve, reject) => {
@@ -33,7 +34,23 @@ function getInputtedParams(promptId, ms = 10000) {
   });
 }
 
-export default async function ({ data, id }) {
+async function renderParamValue(param, refData, isPopup) {
+  const renderedVals = {};
+
+  const keys = ['defaultValue', 'description', 'placeholder'];
+  await Promise.allSettled(
+    keys.map(async (key) => {
+      if (!param[key]) return;
+      renderedVals[key] = (
+        await renderString(param[key], refData, isPopup)
+      ).value;
+    })
+  );
+
+  return { ...param, ...renderedVals };
+}
+
+export default async function ({ data, id }, { refData }) {
   const paramURL = browser.runtime.getURL('/params.html');
   let tab = (await browser.tabs.query({})).find((item) =>
     item.url.includes(paramURL)
@@ -58,14 +75,20 @@ export default async function ({ data, id }) {
   const promptId = `params-prompt:${nanoid(4)}__${id}`;
   const { timeout } = data;
 
+  const params = await Promise.all(
+    data.parameters.map((item) =>
+      renderParamValue(item, refData, this.engine.isPopup)
+    )
+  );
+
   await browser.tabs.sendMessage(tab.id, {
     name: 'workflow:params-block',
     data: {
+      params,
       promptId,
       blockId: id,
       timeoutMs: timeout,
       execId: this.engine.id,
-      params: data.parameters,
       timeout: Date.now() + timeout,
       name: this.engine.workflow.name,
       icon: this.engine.workflow.icon,