|
@@ -4,12 +4,18 @@ import cloneDeep from 'lodash.clonedeep';
|
|
|
import {
|
|
|
jsContentHandler,
|
|
|
automaFetchClient,
|
|
|
-} from '@/newtab/utils/javascriptBlockUtil';
|
|
|
-import { messageSandbox, automaRefDataStr, waitTabLoaded } from '../helper';
|
|
|
+ jsContentHandlerEval,
|
|
|
+} from '../utils/javascriptBlockUtil';
|
|
|
+import {
|
|
|
+ messageSandbox,
|
|
|
+ automaRefDataStr,
|
|
|
+ waitTabLoaded,
|
|
|
+ sendDebugCommand,
|
|
|
+} from '../helper';
|
|
|
|
|
|
const nanoid = customAlphabet('1234567890abcdef', 5);
|
|
|
|
|
|
-function getAutomaScript(varName, refData, everyNewTab) {
|
|
|
+function getAutomaScript(varName, refData, everyNewTab, isEval = false) {
|
|
|
let str = `
|
|
|
const ${varName} = ${JSON.stringify(refData)};
|
|
|
${automaRefDataStr(varName)}
|
|
@@ -17,10 +23,27 @@ function automaSetVariable(name, value) {
|
|
|
${varName}.variables[name] = value;
|
|
|
}
|
|
|
function automaNextBlock(data, insert = true) {
|
|
|
- document.body.dispatchEvent(new CustomEvent('__automa-next-block__', { detail: { data, insert, refData: ${varName} } }));
|
|
|
+ if (${isEval}) {
|
|
|
+ $automaResolve({
|
|
|
+ columns: {
|
|
|
+ data,
|
|
|
+ insert,
|
|
|
+ },
|
|
|
+ variables: ${varName}.variables,
|
|
|
+ });
|
|
|
+ } else{
|
|
|
+ document.body.dispatchEvent(new CustomEvent('__automa-next-block__', { detail: { data, insert, refData: ${varName} } }));
|
|
|
+ }
|
|
|
}
|
|
|
function automaResetTimeout() {
|
|
|
- document.body.dispatchEvent(new CustomEvent('__automa-reset-timeout__'));
|
|
|
+ if (${isEval}) {
|
|
|
+ clearTimeout($automaTimeout);
|
|
|
+ $automaTimeout = setTimeout(() => {
|
|
|
+ resolve();
|
|
|
+ }, $automaTimeoutMs);
|
|
|
+ } else {
|
|
|
+ document.body.dispatchEvent(new CustomEvent('__automa-reset-timeout__'));
|
|
|
+ }
|
|
|
}
|
|
|
function automaFetch(type, resource) {
|
|
|
return (${automaFetchClient.toString()})('${varName}', { type, resource });
|
|
@@ -32,7 +55,11 @@ function automaFetch(type, resource) {
|
|
|
return str;
|
|
|
}
|
|
|
async function executeInWebpage(args, target, worker) {
|
|
|
- if (worker.engine.isMV2 || BROWSER_TYPE === 'firefox') {
|
|
|
+ if (!target.tabId) {
|
|
|
+ throw new Error('no-tab');
|
|
|
+ }
|
|
|
+
|
|
|
+ if (worker.engine.isMV2) {
|
|
|
args[0] = cloneDeep(args[0]);
|
|
|
|
|
|
const result = await worker._sendMessageToTab({
|
|
@@ -43,6 +70,77 @@ async function executeInWebpage(args, target, worker) {
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
+ const [isBlockedByCSP] = await browser.scripting.executeScript({
|
|
|
+ target,
|
|
|
+ func: () => {
|
|
|
+ return new Promise((resolve) => {
|
|
|
+ const eventListener = ({ srcElement }) => {
|
|
|
+ if (!srcElement || srcElement.id !== 'automa-csp') return;
|
|
|
+ srcElement.remove();
|
|
|
+ resolve(true);
|
|
|
+ };
|
|
|
+ document.addEventListener('securitypolicyviolation', eventListener);
|
|
|
+ const script = document.createElement('script');
|
|
|
+ script.id = 'automa-csp';
|
|
|
+ script.innerText = 'console.log("...")';
|
|
|
+
|
|
|
+ setTimeout(() => {
|
|
|
+ document.removeEventListener(
|
|
|
+ 'securitypolicyviolation',
|
|
|
+ eventListener
|
|
|
+ );
|
|
|
+ script.remove();
|
|
|
+ resolve(false);
|
|
|
+ }, 500);
|
|
|
+
|
|
|
+ document.body.appendChild(script);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ world: 'MAIN',
|
|
|
+ });
|
|
|
+
|
|
|
+ if (isBlockedByCSP.result) {
|
|
|
+ await new Promise((resolve) => {
|
|
|
+ chrome.debugger.attach({ tabId: target.tabId }, '1.3', resolve);
|
|
|
+ });
|
|
|
+ const { 0: blockData, 1: preloadScripts, 3: varName } = args;
|
|
|
+ const automaScript = getAutomaScript(
|
|
|
+ varName,
|
|
|
+ blockData.refData,
|
|
|
+ blockData.data.everyNewTab,
|
|
|
+ true
|
|
|
+ );
|
|
|
+ const jsCode = jsContentHandlerEval({
|
|
|
+ blockData,
|
|
|
+ automaScript,
|
|
|
+ preloadScripts,
|
|
|
+ });
|
|
|
+
|
|
|
+ const execResult = await sendDebugCommand(
|
|
|
+ target.tabId,
|
|
|
+ 'Runtime.evaluate',
|
|
|
+ {
|
|
|
+ expression: jsCode,
|
|
|
+ userGesture: true,
|
|
|
+ awaitPromise: true,
|
|
|
+ returnByValue: true,
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ const { debugMode } = worker.engine.workflow.settings;
|
|
|
+ if (!debugMode) await chrome.debugger.detach({ tabId: target.tabId });
|
|
|
+
|
|
|
+ if (!execResult || !execResult.result) {
|
|
|
+ throw new Error('Unable execute code');
|
|
|
+ }
|
|
|
+
|
|
|
+ if (execResult.result.subtype === 'error') {
|
|
|
+ throw new Error(execResult.description);
|
|
|
+ }
|
|
|
+
|
|
|
+ return execResult.result.value || null;
|
|
|
+ }
|
|
|
+
|
|
|
const [{ result }] = await browser.scripting.executeScript({
|
|
|
args,
|
|
|
target,
|
|
@@ -102,7 +200,7 @@ export async function javascriptCode({ outputs, data, ...block }, { refData }) {
|
|
|
|
|
|
const instanceId = `automa${nanoid()}`;
|
|
|
const automaScript =
|
|
|
- data.everyNewTab || data.context === 'background'
|
|
|
+ data.everyNewTab && (!data.context || data.context !== 'background')
|
|
|
? ''
|
|
|
: getAutomaScript(instanceId, payload.refData, data.everyNewTab);
|
|
|
|