Browse Source

fix: conditions block not working in firefox

Ahmad Kholid 2 years ago
parent
commit
081903e93c

+ 2 - 0
src/components/newtab/shared/SharedConditionBuilder/ConditionBuilderInputs.vue

@@ -36,6 +36,7 @@
             <option
               v-for="context in ['website', 'background']"
               :key="context"
+              :disabled="isFirefox && context === 'background'"
               :value="context"
             >
               {{
@@ -123,6 +124,7 @@ const props = defineProps({
 });
 const emit = defineEmits(['update']);
 
+const isFirefox = BROWSER_TYPE === 'firefox';
 const autocompleteList = [automaFuncsSnippets.automaRefData];
 const codemirrorExts = [
   autocompletion({

+ 50 - 0
src/content/blocksHandler/handlerConditions.js

@@ -1,6 +1,10 @@
+import { customAlphabet } from 'nanoid/non-secure';
 import { visibleInViewport, isXPath } from '@/utils/helper';
+import { automaRefDataStr } from '@/newtab/workflowEngine/helper';
 import handleSelector from '../handleSelector';
 
+const nanoid = customAlphabet('1234567890abcdef', 5);
+
 async function handleConditionElement({ data, type, id, frameSelector }) {
   const selectorType = isXPath(data.selector) ? 'xpath' : 'cssSelector';
 
@@ -49,11 +53,57 @@ async function handleConditionElement({ data, type, id, frameSelector }) {
   return elementActions[actionType](data);
 }
 
+async function handleConditionCode({ data, refData }) {
+  return new Promise((resolve, reject) => {
+    const varName = `automa${nanoid()}`;
+
+    const scriptEl = document.createElement('script');
+    scriptEl.textContent = `
+      (async () => {
+        const ${varName} = ${JSON.stringify(refData)};
+        ${automaRefDataStr(varName)}
+        try {
+          ${data.code}
+        } catch (error) {
+          return {
+            $isError: true,
+            message: error.message,
+          }
+        }
+      })()
+        .then((detail) => {
+          window.dispatchEvent(new CustomEvent('__automa-condition-code__', { detail }));
+        });
+    `;
+
+    document.body.appendChild(scriptEl);
+
+    const handleAutomaEvent = ({ detail }) => {
+      scriptEl.remove();
+      window.removeEventListener(
+        '__automa-condition-code__',
+        handleAutomaEvent
+      );
+
+      if (detail.$isError) {
+        reject(new Error(detail.message));
+        return;
+      }
+
+      resolve(detail);
+    };
+
+    window.addEventListener('__automa-condition-code__', handleAutomaEvent);
+  });
+}
+
 export default async function (data) {
   let result = null;
 
   if (data.type.startsWith('element')) {
     result = await handleConditionElement(data);
+  } else if (data.type.startsWith('code')) {
+    result = await handleConditionCode(data);
   }
 
   return result;

+ 1 - 0
src/newtab/workflowEngine/blocksHandler/handlerConditions.js

@@ -131,6 +131,7 @@ async function conditions({ data, id }, { prevBlockData, refData }) {
   if (condition && condition.conditions) {
     const conditionPayload = {
       refData,
+      isMV2: this.engine.isMV2,
       checkCodeCondition: (payload) =>
         checkCodeCondition(this.activeTab, payload),
       sendMessage: (payload) =>

+ 18 - 7
src/newtab/workflowEngine/injectContentScript.js

@@ -1,5 +1,7 @@
 import browser from 'webextension-polyfill';
 
+const isMV2 = browser.runtime.getManifest().manifest_version === 2;
+
 async function contentScriptExist(tabId, frameId = 0) {
   try {
     await browser.tabs.sendMessage(
@@ -28,14 +30,23 @@ export default function (tabId, frameId = 0) {
 
         tryCount += 1;
 
-        await browser.scripting.executeScript({
-          target: {
-            tabId,
+        if (isMV2) {
+          await browser.tabs.executeScript(tabId, {
             allFrames: true,
-          },
-          injectImmediately: true,
-          files: ['./contentScript.bundle.js'],
-        });
+            runAt: 'document_start',
+            file: './contentScript.bundle.js',
+          });
+        } else {
+          await browser.scripting.executeScript({
+            target: {
+              tabId,
+              allFrames: true,
+            },
+            injectImmediately: true,
+            files: ['./contentScript.bundle.js'],
+          });
+        }
+
         const isScriptExists = await contentScriptExist(tabId, currentFrameId);
 
         if (isScriptExists) {

+ 17 - 4
src/utils/testConditions.js

@@ -61,10 +61,23 @@ export default async function (conditionsArr, workflowData) {
     if (type === 'value') return copyData.value;
 
     if (type.startsWith('code')) {
-      const conditionValue = await workflowData.checkCodeCondition({
-        data: copyData,
-        refData: workflowData.refData,
-      });
+      let conditionValue;
+
+      if (workflowData.isMV2) {
+        conditionValue = await workflowData.sendMessage({
+          type: 'condition-builder',
+          data: {
+            type,
+            data: copyData,
+            refData: workflowData.refData,
+          },
+        });
+      } else {
+        conditionValue = await workflowData.checkCodeCondition({
+          data: copyData,
+          refData: workflowData.refData,
+        });
+      }
 
       return conditionValue;
     }