Browse Source

feat: add `insert to clipboard` option in clipboard block

Ahmad Kholid 3 years ago
parent
commit
8193116f78

+ 50 - 14
src/background/workflowEngine/blocksHandler/handlerClipboard.js

@@ -1,6 +1,28 @@
 import browser from 'webextension-polyfill';
 
-export default async function ({ data, id }) {
+function doCommand(command, value) {
+  const textarea = document.createElement('textarea');
+  document.body.appendChild(textarea);
+
+  if (command === 'paste') {
+    textarea.focus();
+    document.execCommand('paste');
+    textarea.remove();
+
+    return textarea.value;
+  }
+  if (command === 'copy') {
+    textarea.value = value;
+    textarea.select();
+    document.execCommand('copy');
+    textarea.blur();
+    textarea.remove();
+  }
+
+  return '';
+}
+
+export default async function ({ data, id, label }) {
   const hasPermission = await browser.permissions.contains({
     permissions: ['clipboardRead'],
   });
@@ -9,24 +31,38 @@ export default async function ({ data, id }) {
     throw new Error('no-clipboard-acces');
   }
 
-  const textarea = document.createElement('textarea');
-  document.body.appendChild(textarea);
-  textarea.focus();
-  document.execCommand('paste');
+  let valueToReturn = '';
 
-  const copiedText = textarea.value;
+  if (!data.type || data.type === 'get') {
+    const copiedText = doCommand('paste');
+    valueToReturn = copiedText;
 
-  if (data.assignVariable) {
-    this.setVariable(data.variableName, copiedText);
-  }
-  if (data.saveData) {
-    this.addDataToColumn(data.dataColumn, copiedText);
-  }
+    if (data.assignVariable) {
+      this.setVariable(data.variableName, copiedText);
+    }
+    if (data.saveData) {
+      this.addDataToColumn(data.dataColumn, copiedText);
+    }
+  } else if (data.type === 'insert') {
+    let text = '';
+
+    if (data.copySelectedText) {
+      if (!this.activeTab.id) throw new Error('no-tab');
 
-  document.body.removeChild(textarea);
+      text = await this._sendMessageToTab({
+        id,
+        label,
+      });
+    } else {
+      text = data.dataToCopy;
+    }
+
+    valueToReturn = text;
+    doCommand('copy', text);
+  }
 
   return {
-    data: copiedText,
+    data: valueToReturn,
     nextBlockId: this.getBlockConnections(id),
   };
 }

+ 33 - 4
src/components/newtab/workflow/edit/EditClipboard.vue

@@ -7,10 +7,37 @@
       @change="updateData({ description: $event })"
     />
     <template v-if="permission.has.clipboardRead">
-      <p class="mt-4">
-        {{ t('workflow.blocks.clipboard.data') }}
-      </p>
-      <insert-workflow-data :data="data" variables @update="updateData" />
+      <ui-select
+        :model-value="data.type"
+        class="mt-4 w-full"
+        @change="updateData({ type: $event })"
+      >
+        <option v-for="type in types" :key="type" :value="type">
+          {{ t(`workflow.blocks.clipboard.types.${type}`) }}
+        </option>
+      </ui-select>
+      <insert-workflow-data
+        v-if="data.type === 'get'"
+        :data="data"
+        variables
+        @update="updateData"
+      />
+      <template v-else>
+        <ui-textarea
+          v-if="!data.copySelectedText"
+          :model-value="data.dataToCopy"
+          placeholder="Text"
+          class="mt-4"
+          @change="updateData({ dataToCopy: $event })"
+        />
+        <ui-checkbox
+          :model-value="data.copySelectedText"
+          class="mt-2"
+          @change="updateData({ copySelectedText: $event })"
+        >
+          {{ t('workflow.blocks.clipboard.copySelection') }}
+        </ui-checkbox>
+      </template>
     </template>
     <template v-else>
       <p class="mt-4">
@@ -35,6 +62,8 @@ const props = defineProps({
 });
 const emit = defineEmits(['update:data']);
 
+const types = ['get', 'insert'];
+
 const { t } = useI18n();
 const permission = useHasPermissions(['clipboardRead']);
 

+ 8 - 0
src/content/blocksHandler/handlerClipboard.js

@@ -0,0 +1,8 @@
+function clipboard() {
+  return new Promise((resolve) => {
+    const text = window.getSelection().toString();
+    resolve(text);
+  });
+}
+
+export default clipboard;

+ 6 - 1
src/locales/en/blocks.json

@@ -170,7 +170,12 @@
         "description": "Get the copied text from the clipboard",
         "data": "Clipboard data",
         "noPermission": "Don't have permission to access the clipboard",
-        "grantPermission": "Grant permission"
+        "grantPermission": "Grant permission",
+        "copySelection": "Copy the selected text on page",
+        "types": {
+          "get": "Get clipboard data",
+          "insert": "Insert text to clipboard"
+        }
       },
       "hover-element": {
         "name": "Hover element",

+ 7 - 0
src/newtab/pages/workflows/[id].vue

@@ -470,6 +470,13 @@ function onEditorInit(instance) {
   instance.onEdgesChange(onEdgesChange);
   instance.onNodesChange(onNodesChange);
 
+  instance.removeSelectedNodes(
+    instance.getSelectedNodes.value.map(({ id }) => id)
+  );
+  instance.removeSelectedEdges(
+    instance.getSelectedEdges.value.map(({ id }) => id)
+  );
+
   const { blockId } = route.query;
   if (blockId) {
     const block = instance.getNode.value(blockId);

+ 4 - 0
src/utils/shared.js

@@ -749,13 +749,17 @@ export const tasks = {
     allowedInputs: true,
     maxConnection: 1,
     autocomplete: ['variableName'],
+    refDataKeys: ['dataToCopy'],
     data: {
       disableBlock: false,
       description: '',
+      type: 'get',
       assignVariable: false,
       variableName: '',
       saveData: true,
       dataColumn: '',
+      dataToCopy: '',
+      copySelectedText: false,
     },
   },
   'insert-data': {