Browse Source

fix: create element JS not working on some website

Ahmad Kholid 2 years ago
parent
commit
8667a252f4

+ 11 - 1
src/content/blocksHandler/handlerCreateElement.js

@@ -37,7 +37,17 @@ async function createElement(block) {
     document.body.appendChild(style);
   }
 
-  if (data.injectJS) {
+  if (block.preloadCSS) {
+    block.preloadCSS.forEach((style) => {
+      const script = document.createElement('style');
+      script.id = `${baseId}-script`;
+      script.textContent = style.script;
+
+      document.body.appendChild(script);
+    });
+  }
+
+  if (!data?.dontInjectJS) {
     data.preloadScripts.forEach((item) => {
       const script = document.createElement(item.type);
       script.id = `${baseId}-script`;

+ 62 - 28
src/workflowEngine/blocksHandler/handlerCreateElement.js

@@ -1,6 +1,6 @@
 import { customAlphabet } from 'nanoid/non-secure';
 import browser from 'webextension-polyfill';
-import { automaRefDataStr } from '../helper';
+import { automaRefDataStr, checkCSPAndInject } from '../helper';
 
 const nanoid = customAlphabet('1234567890abcdef', 5);
 
@@ -45,46 +45,80 @@ async function handleCreateElement(block, { refData }) {
 
   data.preloadScripts = preloadScripts;
 
-  const payload = { ...block, data };
+  const payload = {
+    ...block,
+    data,
+    preloadCSS: data.preloadScripts.filter((item) => item.type === 'style'),
+  };
 
   if (data.javascript && !this.engine.isMV2) {
-    payload.data.injectJS = true;
+    payload.data.dontInjectJS = true;
     payload.data.automaScript = getAutomaScript({ ...refData, secrets: {} });
   }
 
   await this._sendMessageToTab(payload, {}, data.runBeforeLoad ?? false);
 
   if (data.javascript && !this.engine.isMV2) {
-    await browser.scripting.executeScript({
-      world: 'MAIN',
-      args: [
-        data.javascript,
-        block.id,
-        payload.data?.automaScript || '',
-        preloadScripts,
-      ],
-      target: {
-        tabId: this.activeTab.id,
-        frameIds: [this.activeTab.frameId || 0],
+    const target = {
+      tabId: this.activeTab.id,
+      frameIds: [this.activeTab.frameId || 0],
+    };
+
+    const { debugMode } = this.engine.workflow?.settings || {};
+    const result = await checkCSPAndInject(
+      {
+        target,
+        debugMode,
+        options: {
+          awaitPromise: false,
+          returnByValue: false,
+        },
       },
-      func: (code, blockId, $automaScript, $preloadScripts) => {
-        const baseId = `automa-${blockId}`;
-
-        $preloadScripts.forEach((item) => {
-          const script = document.createElement(item.type);
-          script.id = `${baseId}-script`;
-          script.textContent = item.script;
+      () => {
+        let jsPreload = '';
+        preloadScripts.forEach((item) => {
+          if (item.type === 'style') return;
 
-          document.body.appendChild(script);
+          jsPreload += `${item.script}\n`;
         });
 
-        const script = document.createElement('script');
-        script.id = `${baseId}-javascript`;
-        script.textContent = `(() => { ${$automaScript}\n${code} })()`;
+        const automaScript = payload.data?.automaScript || '';
 
-        document.body.appendChild(script);
-      },
-    });
+        return `(() => { ${jsPreload} \n ${automaScript}\n${data.javascript} })()`;
+      }
+    );
+
+    if (!result.isBlocked) {
+      await browser.scripting.executeScript({
+        world: 'MAIN',
+        target,
+        args: [
+          data.javascript,
+          block.id,
+          payload.data?.automaScript || '',
+          preloadScripts,
+        ],
+        func: (code, blockId, $automaScript, $preloadScripts) => {
+          const baseId = `automa-${blockId}`;
+
+          $preloadScripts.forEach((item) => {
+            if (item.type === 'style') return;
+
+            const script = document.createElement(item.type);
+            script.id = `${baseId}-script`;
+            script.textContent = item.script;
+
+            document.body.appendChild(script);
+          });
+
+          const script = document.createElement('script');
+          script.id = `${baseId}-javascript`;
+          script.textContent = `(() => { ${$automaScript}\n${code} })()`;
+
+          document.body.appendChild(script);
+        },
+      });
+    }
   }
 
   return {

+ 5 - 1
src/workflowEngine/helper.js

@@ -214,7 +214,10 @@ export function injectPreloadScript({ target, scripts, frameSelector }) {
   });
 }
 
-export async function checkCSPAndInject({ target, debugMode }, callback) {
+export async function checkCSPAndInject(
+  { target, debugMode, options = {} },
+  callback
+) {
   const [isBlockedByCSP] = await browser.scripting.executeScript({
     target,
     func: () => {
@@ -258,6 +261,7 @@ export async function checkCSPAndInject({ target, debugMode }, callback) {
         userGesture: true,
         awaitPromise: true,
         returnByValue: true,
+        ...(options || {}),
       }
     );
 

+ 6 - 2
src/workflowEngine/templating/renderString.js

@@ -15,7 +15,8 @@ export default async function (str, data, isPopup = true) {
   }
 
   let renderedValue = {};
-  if (str.startsWith('!!') && !isFirefox && isPopup) {
+  const evaluateJS = str.startsWith('!!');
+  if (evaluateJS && !isFirefox && isPopup) {
     const refKeysRegex =
       /(variables|table|secrets|loopData|workflow|googleSheets|globalData)@/g;
     const strToRender = str.replace(refKeysRegex, '$1.');
@@ -25,7 +26,10 @@ export default async function (str, data, isPopup = true) {
       data,
     });
   } else {
-    renderedValue = mustacheReplacer(str, data);
+    let copyStr = `${str}`;
+    if (evaluateJS) copyStr = copyStr.slice(2);
+
+    renderedValue = mustacheReplacer(copyStr, data);
   }
 
   return renderedValue;