Browse Source

feat: add "element visible and hidden in viewport" in the condition builder

Ahmad Kholid 3 years ago
parent
commit
f279278d89

+ 5 - 2
src/content/handleSelector.js

@@ -1,5 +1,5 @@
 import FindElement from '@/utils/FindElement';
-import { scrollIfNeeded } from '@/utils/helper';
+import { visibleInViewport } from '@/utils/helper';
 
 /* eslint-disable consistent-return */
 
@@ -83,7 +83,10 @@ export default async function (
       elementsArr.map(async (el) => {
         markElement(el, { id, data });
 
-        if (debugMode) scrollIfNeeded(el);
+        if (debugMode) {
+          const isInViewport = visibleInViewport(el);
+          if (!isInViewport) el.scrollIntoView();
+        }
 
         if (onSelected) await onSelected(el);
       })

+ 3 - 0
src/content/handleTestCondition.js

@@ -1,4 +1,5 @@
 import { nanoid } from 'nanoid';
+import { visibleInViewport } from '@/utils/helper';
 import FindElement from '@/utils/FindElement';
 import { automaRefDataStr } from './utils';
 
@@ -11,6 +12,8 @@ function handleConditionElement({ data, type }) {
   const elementActions = {
     exists: () => Boolean(element),
     text: () => element?.innerText ?? null,
+    visibleInViewport: () => visibleInViewport(element),
+    hiddenInViewport: () => !elementActions.visibleInViewport(),
     visible: () => {
       if (!element) return false;
 

+ 1 - 1
src/locales/en/newtab.json

@@ -110,7 +110,7 @@
       "add": "Add condition",
       "and": "AND",
       "or": "OR",
-      "topAwait": "Support top-level await"
+      "topAwait": "Support top-level await and \"automaRefData\" function"
     },
     "host": {
       "title": "Host workflow",

+ 9 - 8
src/utils/helper.js

@@ -1,16 +1,17 @@
 import browser from 'webextension-polyfill';
 
-export function scrollIfNeeded(element) {
-  const { top, left, bottom, right } = element.getBoundingClientRect();
-  const isInViewport =
+export function visibleInViewport(element) {
+  const { top, left, bottom, right, height, width } =
+    element.getBoundingClientRect();
+
+  if (height === 0 || width === 0) return false;
+
+  return (
     top >= 0 &&
     left >= 0 &&
     bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
-    right <= (window.innerWidth || document.documentElement.clientWidth);
-
-  if (!isInViewport) {
-    element.scrollIntoView();
-  }
+    right <= (window.innerWidth || document.documentElement.clientWidth)
+  );
 }
 
 export function sleep(timeout = 500) {

+ 14 - 0
src/utils/shared.js

@@ -1099,6 +1099,20 @@ export const conditionBuilder = {
       compareable: false,
       data: { selector: '' },
     },
+    {
+      id: 'element#visibleInViewport',
+      category: 'element',
+      name: 'Element visible in viewport',
+      compareable: false,
+      data: { selector: '' },
+    },
+    {
+      id: 'element#hiddenInViewport',
+      category: 'element',
+      name: 'Element hidden in viewport',
+      compareable: false,
+      data: { selector: '' },
+    },
     {
       id: 'element#attribute',
       category: 'element',