@midscene/web 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -580,9 +580,6 @@ var midscene_element_inspector = (() => {
580
580
  extractTextWithPosition: () => extractTextWithPosition
581
581
  });
582
582
 
583
- // src/extractor/constants.ts
584
- var TEXT_SIZE_THRESHOLD = 9;
585
-
586
583
  // src/extractor/dom-util.ts
587
584
  function isInputElement(node) {
588
585
  return node instanceof HTMLElement && (node.tagName.toLowerCase() === "input" || node.tagName.toLowerCase() === "textarea");
@@ -593,10 +590,21 @@ var midscene_element_inspector = (() => {
593
590
  function isImgElement(node) {
594
591
  return node instanceof HTMLElement && node.tagName.toLowerCase() === "img";
595
592
  }
593
+ function isTextElement(node) {
594
+ return node.nodeName.toLowerCase() === "#text";
595
+ }
596
596
 
597
597
  // src/extractor/util.ts
598
598
  var import_js_sha256 = __toESM(require_sha256());
599
+ var debugMode = false;
600
+ function setDebugMode(mode) {
601
+ debugMode = mode;
602
+ }
599
603
  function logger(..._msg) {
604
+ if (!debugMode) {
605
+ return;
606
+ }
607
+ console.log(..._msg);
600
608
  }
601
609
  var taskIdKey = "_midscene_retrieve_task_id";
602
610
  function selectorForValue(val) {
@@ -626,40 +634,61 @@ var midscene_element_inspector = (() => {
626
634
  after: afterContent === "none" ? "" : afterContent.replace(/"/g, "")
627
635
  };
628
636
  }
637
+ function getRect(el) {
638
+ if (!(el instanceof HTMLElement)) {
639
+ const range = document.createRange();
640
+ range.selectNodeContents(el);
641
+ return range.getBoundingClientRect();
642
+ }
643
+ return el.getBoundingClientRect();
644
+ }
629
645
  function visibleRect(el) {
630
646
  if (!el) {
631
- logger("Element is not in the DOM hierarchy");
647
+ logger(el, "Element is not in the DOM hierarchy");
632
648
  return false;
633
649
  }
634
- if (!(el instanceof HTMLElement)) {
635
- logger("Element is not in the DOM hierarchy");
650
+ if (!(el instanceof HTMLElement) && el.nodeType !== Node.TEXT_NODE) {
651
+ logger(el, "Element is not in the DOM hierarchy");
636
652
  return false;
637
653
  }
638
- const style = window.getComputedStyle(el);
639
- if (style.display === "none" || style.visibility === "hidden" || style.opacity === "0" && el.tagName !== "INPUT") {
640
- logger("Element is hidden");
641
- return false;
654
+ if (el instanceof HTMLElement) {
655
+ const style = window.getComputedStyle(el);
656
+ if (style.display === "none" || style.visibility === "hidden" || style.opacity === "0" && el.tagName !== "INPUT") {
657
+ logger(el, "Element is hidden");
658
+ return false;
659
+ }
642
660
  }
643
- const rect = el.getBoundingClientRect();
661
+ const rect = getRect(el);
644
662
  if (rect.width === 0 && rect.height === 0) {
645
- logger("Element has no size");
663
+ logger(el, "Element has no size");
646
664
  return false;
647
665
  }
648
666
  const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
649
667
  const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
650
- const isInViewport = rect.top >= 0 + scrollTop && rect.left >= 0 + scrollLeft && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) + scrollTop && rect.right <= (window.innerWidth || document.documentElement.clientWidth) + scrollLeft;
651
- if (!isInViewport) {
652
- logger("Element is not in the viewport");
653
- logger(rect, window.innerHeight, window.innerWidth, scrollTop, scrollLeft);
668
+ const viewportWidth = window.innerWidth || document.documentElement.clientWidth;
669
+ const viewportHeight = window.innerHeight || document.documentElement.clientHeight;
670
+ const isPartiallyInViewport = rect.right > 0 && rect.bottom > 0 && rect.left < viewportWidth && rect.top < viewportHeight;
671
+ if (!isPartiallyInViewport) {
672
+ logger(el, "Element is completely outside the viewport", {
673
+ rect,
674
+ viewportHeight,
675
+ viewportWidth,
676
+ scrollTop,
677
+ scrollLeft
678
+ });
654
679
  return false;
655
680
  }
656
681
  let parent = el;
657
682
  while (parent && parent !== document.body) {
683
+ if (!(parent instanceof HTMLElement)) {
684
+ parent = parent.parentElement;
685
+ continue;
686
+ }
658
687
  const parentStyle = window.getComputedStyle(parent);
659
688
  if (parentStyle.overflow === "hidden") {
660
689
  const parentRect = parent.getBoundingClientRect();
661
690
  const tolerance = 10;
662
- if (rect.top < parentRect.top - tolerance || rect.left < parentRect.left - tolerance || rect.bottom > parentRect.bottom + tolerance || rect.right > parentRect.right + tolerance) {
691
+ if (rect.top < parentRect.top - tolerance && rect.left < parentRect.left - tolerance && rect.bottom > parentRect.bottom + tolerance && rect.right > parentRect.right + tolerance) {
663
692
  logger("Element is clipped by an ancestor", parent, rect, parentRect);
664
693
  return false;
665
694
  }
@@ -673,29 +702,6 @@ var midscene_element_inspector = (() => {
673
702
  height: Math.round(rect.height)
674
703
  };
675
704
  }
676
- function validTextNodeContent(node) {
677
- if (!node) {
678
- return false;
679
- }
680
- if (node.nodeType !== Node.ELEMENT_NODE && node.nodeType !== Node.TEXT_NODE) {
681
- return false;
682
- }
683
- const everyChildNodeIsText = Array.from(node.childNodes).every((child) => {
684
- const tagName = (child.tagName || "").toLowerCase();
685
- if (tagName === "script" || tagName === "style" || tagName === "link") {
686
- return false;
687
- }
688
- return true;
689
- });
690
- if (!everyChildNodeIsText) {
691
- return false;
692
- }
693
- const content = node.textContent || node.innerText;
694
- if (content && !/^\s*$/.test(content)) {
695
- return content.trim();
696
- }
697
- return false;
698
- }
699
705
  function getNodeAttributes(node) {
700
706
  if (!node || !(node instanceof HTMLElement) || !node.attributes) {
701
707
  return {};
@@ -723,7 +729,8 @@ var midscene_element_inspector = (() => {
723
729
  function generateId(numberId) {
724
730
  return `${numberId}`;
725
731
  }
726
- function extractTextWithPosition(initNode = container) {
732
+ function extractTextWithPosition(initNode = container, debugMode2 = false) {
733
+ setDebugMode(debugMode2);
727
734
  const elementInfoArray = [];
728
735
  const nodeMapTree = { node: initNode, children: [] };
729
736
  let nodeIndex = 1;
@@ -735,17 +742,22 @@ var midscene_element_inspector = (() => {
735
742
  if (parentNode == null ? void 0 : parentNode.children) {
736
743
  parentNode.children.push(currentNodeDes);
737
744
  }
738
- collectElementInfo(node);
745
+ const shouldContinue = collectElementInfo(node);
746
+ if (!shouldContinue) {
747
+ return;
748
+ }
739
749
  for (let i = 0; i < node.childNodes.length; i++) {
740
750
  logger("will dfs", node.childNodes[i]);
741
751
  dfs(node.childNodes[i], currentNodeDes);
742
752
  }
743
753
  }
744
754
  function collectElementInfo(node) {
755
+ var _a;
745
756
  const rect = visibleRect(node);
757
+ logger("collectElementInfo", node, node.nodeName, rect);
746
758
  if (!rect) {
747
759
  logger("Element is not visible", node);
748
- return;
760
+ return true;
749
761
  }
750
762
  if (isInputElement(node)) {
751
763
  const attributes = getNodeAttributes(node);
@@ -756,6 +768,7 @@ var midscene_element_inspector = (() => {
756
768
  indexId: generateId(nodeIndex++),
757
769
  nodeHashId,
758
770
  locator: selector,
771
+ nodeType: "INPUT Node" /* INPUT */,
759
772
  attributes: __spreadProps(__spreadValues({}, attributes), {
760
773
  nodeType: "INPUT Node" /* INPUT */
761
774
  }),
@@ -764,7 +777,8 @@ var midscene_element_inspector = (() => {
764
777
  center: [
765
778
  Math.round(rect.left + rect.width / 2),
766
779
  Math.round(rect.top + rect.height / 2)
767
- ]
780
+ ],
781
+ htmlNode: debugMode2 ? node : null
768
782
  });
769
783
  return;
770
784
  }
@@ -778,6 +792,7 @@ var midscene_element_inspector = (() => {
778
792
  id: nodeHashId,
779
793
  indexId: generateId(nodeIndex++),
780
794
  nodeHashId,
795
+ nodeType: "BUTTON Node" /* BUTTON */,
781
796
  locator: selector,
782
797
  attributes: __spreadProps(__spreadValues({}, attributes), {
783
798
  nodeType: "BUTTON Node" /* BUTTON */
@@ -787,7 +802,8 @@ var midscene_element_inspector = (() => {
787
802
  center: [
788
803
  Math.round(rect.left + rect.width / 2),
789
804
  Math.round(rect.top + rect.height / 2)
790
- ]
805
+ ],
806
+ htmlNode: debugMode2 ? node : null
791
807
  });
792
808
  return;
793
809
  }
@@ -803,19 +819,20 @@ var midscene_element_inspector = (() => {
803
819
  attributes: __spreadProps(__spreadValues({}, attributes), {
804
820
  nodeType: "IMG Node" /* IMG */
805
821
  }),
822
+ nodeType: "IMG Node" /* IMG */,
806
823
  content: "",
807
824
  rect,
808
825
  center: [
809
826
  Math.round(rect.left + rect.width / 2),
810
827
  Math.round(rect.top + rect.height / 2)
811
- ]
828
+ ],
829
+ htmlNode: debugMode2 ? node : null
812
830
  });
813
831
  return;
814
832
  }
815
- const text = validTextNodeContent(node);
816
- if (text) {
817
- if (rect.width < TEXT_SIZE_THRESHOLD || rect.height < TEXT_SIZE_THRESHOLD) {
818
- logger("Element is too small", text);
833
+ if (isTextElement(node)) {
834
+ const text = (_a = node.textContent) == null ? void 0 : _a.trim().replace(/\n+/g, " ");
835
+ if (!text) {
819
836
  return;
820
837
  }
821
838
  const attributes = getNodeAttributes(node);
@@ -825,19 +842,23 @@ var midscene_element_inspector = (() => {
825
842
  id: nodeHashId,
826
843
  indexId: generateId(nodeIndex++),
827
844
  nodeHashId,
845
+ nodeType: "TEXT Node" /* TEXT */,
846
+ locator: selector,
828
847
  attributes: __spreadProps(__spreadValues({}, attributes), {
829
848
  nodeType: "TEXT Node" /* TEXT */
830
849
  }),
831
- locator: selector,
832
850
  center: [
833
851
  Math.round(rect.left + rect.width / 2),
834
852
  Math.round(rect.top + rect.height / 2)
835
853
  ],
836
854
  // attributes,
837
855
  content: text,
838
- rect
856
+ rect,
857
+ htmlNode: debugMode2 ? node : null
839
858
  });
859
+ return;
840
860
  }
861
+ return true;
841
862
  }
842
863
  dfs(initNode, nodeMapTree);
843
864
  return elementInfoArray;