Skip to content

Commit

Permalink
feat: add "javascript code" block
Browse files Browse the repository at this point in the history
  • Loading branch information
Kholid060 committed Nov 6, 2021
1 parent fea76c3 commit 36b6c5f
Show file tree
Hide file tree
Showing 15 changed files with 293 additions and 74 deletions.
13 changes: 13 additions & 0 deletions src/assets/css/prism-editor.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.my-editor,
.prism-editor-wrapper {
color: #ccc;
font-family: JetBrains Mono, Fira code, Fira Mono, Consolas, Menlo, Courier,
monospace;
font-size: 14px;
line-height: 1.5;
padding: 5px;
@apply bg-gray-900 rounded-lg;
}
.prism-editor__textarea:focus {
outline: none;
}
59 changes: 49 additions & 10 deletions src/background/blocks-handler.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable no-underscore-dangle */
import browser from 'webextension-polyfill';
import { objectHasKey, fileSaver } from '@/utils/helper';
import { objectHasKey, fileSaver, isObject } from '@/utils/helper';
import { tasks } from '@/utils/shared';
import dataExporter from '@/utils/data-exporter';
import compareBlockValue from '@/utils/compare-block-value';
Expand All @@ -26,8 +26,8 @@ function convertData(data, type) {

return result;
}
function generateBlockError(block) {
const message = errorMessage('no-tab', tasks[block.name]);
function generateBlockError(block, code) {
const message = errorMessage(code || 'no-tab', tasks[block.name]);
const error = new Error(message);
error.nextBlockId = getBlockConnection(block);

Expand Down Expand Up @@ -279,22 +279,61 @@ export function interactionHandler(block) {
once: true,
delay: block.name === 'link' ? 5000 : 0,
callback: (data) => {
if (data?.isError) {
const error = new Error(data.message);
error.nextBlockId = nextBlockId;

reject(error);
return;
}

const getColumn = (name) =>
this.workflow.dataColumns.find((item) => item.name === name) || {
name: 'column',
type: 'text',
};
const pushData = (column, value) => {
this.data[column.name]?.push(convertData(value, column.type));
};

if (objectHasKey(block.data, 'dataColumn')) {
const { name, type } = Object.values(this.workflow.dataColumns).find(
(item) => item.name === block.data.dataColumn
) || { name: 'column', type: 'text' };
const column = getColumn(block.data.dataColumn);

if (block.data.saveData) {
if (!objectHasKey(this.data, name)) this.data[name] = [];

if (Array.isArray(data)) {
data.forEach((item) => {
this.data[name].push(convertData(item, type));
pushData(column, item);
});
} else {
this.data[name].push(convertData(data, type));
pushData(column, data);
}
}
} else if (block.name === 'javascript-code') {
const memoColumn = {};
const pushObjectData = (obj) => {
Object.entries(obj).forEach(([key, value]) => {
let column;

if (memoColumn[key]) {
column = memoColumn[key];
} else {
const currentColumn = getColumn(key);

column = currentColumn;
memoColumn[key] = currentColumn;
}

pushData(column, value);
});
};

if (Array.isArray(data)) {
data.forEach((obj) => {
if (isObject(obj)) pushObjectData(obj);
});
} else if (isObject(data)) {
pushObjectData(data);
}
}

resolve({
Expand Down
13 changes: 13 additions & 0 deletions src/background/workflow-engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,21 @@ class WorkflowEngine {
browser.tabs.onUpdated.addListener(this.tabUpdatedHandler);
browser.tabs.onRemoved.addListener(this.tabRemovedHandler);

const dataColumns = Array.isArray(this.workflow.dataColumns)
? this.workflow.dataColumns
: Object.values(this.workflow.dataColumns);

this.blocks = blocks;
this.startedTimestamp = Date.now();
this.workflow.dataColumns = dataColumns;
this.data = dataColumns.reduce(
(acc, column) => {
acc[column.name] = [];

return acc;
},
{ column: [] }
);

workflowState
.add(this.id, {
Expand Down
21 changes: 2 additions & 19 deletions src/components/newtab/logs/LogsDataViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
</div>
<prism-editor
:model-value="dataStr"
:highlight="highlighter"
:highlight="highlighter('json')"
:class="editorClass"
readonly
class="my-editor p-4 bg-gray-900 rounded-lg mt-4"
Expand All @@ -33,12 +33,9 @@
<script setup>
import { ref } from 'vue';
import { PrismEditor } from 'vue-prism-editor';
import { highlight, languages } from 'prismjs/components/prism-core';
import { highlighter } from '@/lib/prism';
import { dataExportTypes } from '@/utils/shared';
import dataExporter, { generateJSON } from '@/utils/data-exporter';
import 'vue-prism-editor/dist/prismeditor.min.css';
import 'prismjs/components/prism-json';
import 'prismjs/themes/prism-tomorrow.css';
const props = defineProps({
log: {
Expand All @@ -55,22 +52,8 @@ const data = generateJSON(Object.keys(props.log.data), props.log.data);
const dataStr = JSON.stringify(data, null, 2);
const fileName = ref(props.log.name);
const highlighter = (code) => highlight(code, languages.json);
function exportData(type) {
dataExporter(data, { name: fileName.value, type }, true);
}
</script>
<style scoped>
.my-editor {
color: #ccc;
font-family: JetBrains Mono, Fira code, Fira Mono, Consolas, Menlo, Courier,
monospace;
font-size: 14px;
line-height: 1.5;
padding: 5px;
}
.prism-editor__textarea:focus {
outline: none;
}
</style>
37 changes: 15 additions & 22 deletions src/components/newtab/workflow/WorkflowEditBlock.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,23 @@
</template>
<script>
import { computed } from 'vue';
import EditForms from './edit/EditForms.vue';
import EditTrigger from './edit/EditTrigger.vue';
import EditGetText from './edit/EditGetText.vue';
import EditCloseTab from './edit/EditCloseTab.vue';
import EditTriggerEvent from './edit/EditTriggerEvent.vue';
import EditElementExists from './edit/EditElementExists.vue';
import EditScrollElement from './edit/EditScrollElement.vue';
import EditAttributeValue from './edit/EditAttributeValue.vue';
import EditTakeScreenshot from './edit/EditTakeScreenshot.vue';
import EditInteractionBase from './edit/EditInteractionBase.vue';
const editComponents = require.context(
'./edit',
false,
/^(?:.*\/)?Edit[^/]*\.vue$/
);
const components = editComponents.keys().reduce((acc, key) => {
const name = key.replace(/(.\/)|\.vue$/g, '');
const componentObj = editComponents(key)?.default ?? {};
acc[name] = componentObj;
return acc;
}, {});
export default {
components: {
EditForms,
EditTrigger,
EditGetText,
EditCloseTab,
EditTriggerEvent,
EditElementExists,
EditScrollElement,
EditAttributeValue,
EditTakeScreenshot,
EditInteractionBase,
},
components,
};
</script>
<script setup>
Expand Down
91 changes: 91 additions & 0 deletions src/components/newtab/workflow/edit/EditJavascriptCode.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<template>
<div class="mb-2 mt-4">
<ui-textarea
:model-value="data.description"
autoresize
placeholder="Description"
class="w-full mb-2"
@change="updateData({ description: $event })"
/>
<ui-input
type="number"
:model-value="data.timeout"
class="mb-2 w-full"
placeholder="Timeout"
title="Javascript code execution timeout"
@change="updateData({ timeout: +$event })"
/>
<prism-editor
v-if="!showCodeModal"
:model-value="data.code"
:highlight="highlighter('javascript')"
readonly
class="p-4 max-h-80"
@click="showCodeModal = true"
/>
<ui-modal
v-model="showCodeModal"
title="Javascript code"
content-class="max-w-3xl"
>
<prism-editor
v-model="code"
class="py-4"
:highlight="highlighter('javascript')"
line-numbers
style="height: calc(100vh - 18rem)"
/>
<div>
Note:
<ol class="list-decimal pl-5">
<li>
To execute the next block, you can call the
<code>automaNextBlock</code> function. This function accepts one
parameter, which you can use to save data to the workflow. Data
format:
<ul class="list-disc space-y-2 mt-2 text-sm pl-5">
<li><code>{ key: value }</code></li>
<li>
<code>[{ key: value }, { key: value }]</code>
</li>
</ul>
You must use the column that you added as a key.
</li>
<li>
To reset the execution timeout of the code, you can call the
<code>automaResetTimeout</code> function.
</li>
</ol>
</div>
</ui-modal>
</div>
</template>
<script setup>
import { ref, watch } from 'vue';
import { PrismEditor } from 'vue-prism-editor';
import { highlighter } from '@/lib/prism';
const props = defineProps({
data: {
type: Object,
default: () => ({}),
},
});
const emit = defineEmits(['update:data']);
const code = ref(props.data.code);
const showCodeModal = ref(false);
function updateData(value) {
emit('update:data', { ...props.data, ...value });
}
watch(code, (value) => {
updateData({ code: value });
});
</script>
<style scoped>
code {
@apply bg-gray-900 text-sm text-white p-1 rounded-md;
}
</style>
6 changes: 5 additions & 1 deletion src/components/ui/UiModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<div class="mb-4">
<div class="flex items-center justify-between">
<span class="content-header">
<slot name="header"></slot>
<slot name="header">{{ title }}</slot>
</span>
<v-remixicon
v-show="!persist"
Expand Down Expand Up @@ -66,6 +66,10 @@ export default {
type: String,
default: 'max-w-lg',
},
title: {
type: String,
default: '',
},
customContent: Boolean,
persist: Boolean,
blur: Boolean,
Expand Down
42 changes: 42 additions & 0 deletions src/content/blocks-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,48 @@ function incScrollPos(element, data, vertical = true) {

return currentPos;
}

const automaScript = `
function automaNextBlock(data) {
window.dispatchEvent(new CustomEvent('__automa-next-block__', { detail: data }));
}
function automaResetTimeout() {
window.dispatchEvent(new CustomEvent('__automa-reset-timeout__'));
}
`;

export function javascriptCode(block) {
return new Promise((resolve) => {
const isScriptExists = document.getElementById('automa-custom-js');

if (isScriptExists) isScriptExists.remove();

const script = document.createElement('script');
let timeout;

script.id = 'automa-custom-js';
script.innerHTML = `${automaScript} ${block.data.code}`;

window.addEventListener('__automa-next-block__', ({ detail }) => {
clearTimeout(timeout);
resolve(detail || {});
});
window.addEventListener('__automa-reset-timeout__', () => {
clearTimeout(timeout);

timeout = setTimeout(() => {
resolve('');
}, block.data.timeout);
});

document.body.appendChild(script);

timeout = setTimeout(() => {
resolve('');
}, block.data.timeout);
});
}

export function elementScroll(block) {
return new Promise((resolve) => {
const { data } = block;
Expand Down
13 changes: 10 additions & 3 deletions src/content/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,16 @@ function onConnectListener() {
const handler = blocksHandler[toCamelCase(data.name)];

if (handler) {
handler(data).then((result) => {
port.postMessage({ type: data.name, data: result });
});
handler(data)
.then((result) => {
port.postMessage({ type: data.name, data: result });
})
.catch((error) => {
port.postMessage({
isError: true,
message: error?.message || error,
});
});
} else {
console.error(`"${data.name}" doesn't have a handler`);
}
Expand Down
Loading

0 comments on commit 36b6c5f

Please sign in to comment.