@coolkiller007/my-page-agent 0.2.6 → 0.2.7

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.
package/dist/index.js CHANGED
@@ -990,6 +990,53 @@ var dom_tree_default = (args = {
990
990
  return false;
991
991
  }
992
992
  /**
993
+ * 判断某元素(或其祖先)是否带有 data-browser-use-ignore / data-page-agent-ignore 标记。
994
+ * 这些是我们自己注入的悬浮 UI(agent 面板、模拟遮罩等),命中测试时应视为"透明"。
995
+ *
996
+ * @param {Element | null} el - 待检查元素。
997
+ * @returns {boolean} 是否应在遮挡检测中被忽略。
998
+ */
999
+ function isIgnoredForHitTest(el) {
1000
+ let current = el;
1001
+ while (current) {
1002
+ if (current.dataset && (current.dataset.browserUseIgnore === "true" || current.dataset.pageAgentIgnore === "true")) return true;
1003
+ current = current.parentElement;
1004
+ }
1005
+ return false;
1006
+ }
1007
+ /**
1008
+ * @edit 命中测试时跳过被忽略的悬浮 UI(agent 面板、模拟遮罩等)。
1009
+ * 之前只有 SimulatorMask 会在 DOM 提取期间临时把 pointerEvents 设为 none 来绕开自己,
1010
+ * 但 agent 自身的问答/历史面板(UI.ts)没有做同样处理 —— 当面板展开、在视觉上盖住
1011
+ * 弹窗等页面元素时,elementFromPoint 命中的是面板本身,导致弹窗被误判为"被遮挡"而从
1012
+ * 提交给 LLM 的可交互树中消失,造成"弹窗仍开着,agent 却认为已关闭"的错觉。
1013
+ * 这里统一在遮挡检测层面处理:命中被忽略元素时临时禁用其 pointer-events 再重新探测,
1014
+ * 探测完成后恢复,使得任何打了忽略标记的悬浮 UI 都不会影响真实页面元素的遮挡判断。
1015
+ *
1016
+ * @param {Document | ShadowRoot} doc - 用于命中测试的文档或 shadow root。
1017
+ * @param {number} x - 命中测试点的 x 坐标。
1018
+ * @param {number} y - 命中测试点的 y 坐标。
1019
+ * @returns {Element | null} 忽略悬浮 UI 后,实际命中的最上层元素。
1020
+ */
1021
+ function elementFromPointSkippingIgnored(doc, x, y) {
1022
+ /** @type {{ el: HTMLElement, prevValue: string }[]} */
1023
+ const restoreList = [];
1024
+ try {
1025
+ let topEl = doc.elementFromPoint(x, y);
1026
+ while (topEl instanceof HTMLElement && isIgnoredForHitTest(topEl)) {
1027
+ restoreList.push({
1028
+ el: topEl,
1029
+ prevValue: topEl.style.pointerEvents
1030
+ });
1031
+ topEl.style.pointerEvents = "none";
1032
+ topEl = doc.elementFromPoint(x, y);
1033
+ }
1034
+ return topEl;
1035
+ } finally {
1036
+ for (const { el, prevValue } of restoreList) el.style.pointerEvents = prevValue;
1037
+ }
1038
+ }
1039
+ /**
993
1040
  * Checks if an element is the topmost element at its position.
994
1041
  *
995
1042
  * @param {HTMLElement} element - The element to check.
@@ -1023,7 +1070,7 @@ var dom_tree_default = (args = {
1023
1070
  const centerX = rect.left + rect.width / 2;
1024
1071
  const centerY = rect.top + rect.height / 2;
1025
1072
  try {
1026
- const topEl = shadowRoot.elementFromPoint(centerX, centerY);
1073
+ const topEl = elementFromPointSkippingIgnored(shadowRoot, centerX, centerY);
1027
1074
  if (!topEl) return false;
1028
1075
  let current = topEl;
1029
1076
  while (current && current !== shadowRoot) {
@@ -1051,7 +1098,7 @@ var dom_tree_default = (args = {
1051
1098
  }
1052
1099
  ].some(({ x, y }) => {
1053
1100
  try {
1054
- const topEl = document.elementFromPoint(x, y);
1101
+ const topEl = elementFromPointSkippingIgnored(document, x, y);
1055
1102
  if (!topEl) return false;
1056
1103
  let current = topEl;
1057
1104
  while (current && current !== document.documentElement) {
@@ -2822,7 +2869,7 @@ var UI = class {
2822
2869
  if (status === "running") {
2823
2870
  this.show();
2824
2871
  this.#hideInputArea();
2825
- if (!this.#isExpanded) this.#expand();
2872
+ if (this.#isExpanded) this.#collapse();
2826
2873
  }
2827
2874
  if (status === "completed" || status === "error" || status === "stopped") {
2828
2875
  if (!this.#isExpanded) this.#expand();