@usecrow/client 0.1.36 → 0.1.38
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/PageController-Cu6KUkcn.cjs +9 -0
- package/dist/{PageController-BweWYS-Z.js → PageController-D3uwrwlG.js} +588 -382
- package/dist/browser.cjs +3 -1
- package/dist/browser.d.ts +84 -0
- package/dist/browser.js +91 -20
- package/dist/index.cjs +3 -3
- package/dist/index.d.ts +415 -0
- package/dist/index.js +7 -6
- package/dist/workflowExecutor-BUc7WzWF.cjs +1 -0
- package/dist/workflowExecutor-DgghvBIA.js +365 -0
- package/package.json +1 -1
- package/dist/PageController-BDcmu8Xe.cjs +0 -9
- package/dist/browserUse-BjeJDX8x.cjs +0 -1
- package/dist/browserUse-Btg7osSj.js +0 -235
|
@@ -2,14 +2,14 @@ async function waitFor(e) {
|
|
|
2
2
|
await new Promise((n) => setTimeout(n, e * 1e3));
|
|
3
3
|
}
|
|
4
4
|
async function movePointerToElement(e) {
|
|
5
|
-
const n = e.getBoundingClientRect(),
|
|
6
|
-
window.dispatchEvent(new CustomEvent("PageAgent::MovePointerTo", { detail: { x:
|
|
5
|
+
const n = e.getBoundingClientRect(), i = n.left + n.width / 2, o = n.top + n.height / 2;
|
|
6
|
+
window.dispatchEvent(new CustomEvent("PageAgent::MovePointerTo", { detail: { x: i, y: o } })), await waitFor(0.3);
|
|
7
7
|
}
|
|
8
8
|
function getElementByIndex(e, n) {
|
|
9
|
-
const
|
|
10
|
-
if (!
|
|
9
|
+
const i = e.get(n);
|
|
10
|
+
if (!i)
|
|
11
11
|
throw new Error(`No interactive element found at index ${n}`);
|
|
12
|
-
const o =
|
|
12
|
+
const o = i.ref;
|
|
13
13
|
if (!o)
|
|
14
14
|
throw new Error(`Element at index ${n} does not have a reference`);
|
|
15
15
|
if (!(o instanceof HTMLElement))
|
|
@@ -38,19 +38,22 @@ function getNativeTextAreaValueSetter() {
|
|
|
38
38
|
"value"
|
|
39
39
|
).set), _nativeTextAreaValueSetter;
|
|
40
40
|
}
|
|
41
|
+
async function createSyntheticInputEvent(e, n) {
|
|
42
|
+
e.dispatchEvent(new KeyboardEvent("keydown", { bubbles: !0, cancelable: !0, key: n })), await waitFor(0.01), (e instanceof HTMLInputElement || e instanceof HTMLTextAreaElement) && (e.dispatchEvent(new Event("beforeinput", { bubbles: !0 })), await waitFor(0.01), e.dispatchEvent(new Event("input", { bubbles: !0 })), await waitFor(0.01)), e.dispatchEvent(new KeyboardEvent("keyup", { bubbles: !0, cancelable: !0, key: n }));
|
|
43
|
+
}
|
|
41
44
|
async function inputTextElement(e, n) {
|
|
42
45
|
if (!(e instanceof HTMLInputElement || e instanceof HTMLTextAreaElement))
|
|
43
46
|
throw new Error("Element is not an input or textarea");
|
|
44
47
|
await clickElement(e), e instanceof HTMLTextAreaElement ? getNativeTextAreaValueSetter().call(e, n) : getNativeInputValueSetter().call(e, n);
|
|
45
|
-
const
|
|
46
|
-
e.dispatchEvent(
|
|
48
|
+
const i = new Event("input", { bubbles: !0 });
|
|
49
|
+
e.dispatchEvent(i), await waitFor(0.1), blurLastClickedElement();
|
|
47
50
|
}
|
|
48
51
|
async function selectOptionElement(e, n) {
|
|
49
52
|
if (!(e instanceof HTMLSelectElement))
|
|
50
53
|
throw new Error("Element is not a select element");
|
|
51
|
-
const o = Array.from(e.options).find((
|
|
54
|
+
const o = Array.from(e.options).find((f) => {
|
|
52
55
|
var d;
|
|
53
|
-
return ((d =
|
|
56
|
+
return ((d = f.textContent) == null ? void 0 : d.trim()) === n.trim();
|
|
54
57
|
});
|
|
55
58
|
if (!o)
|
|
56
59
|
throw new Error(`Option with text "${n}" not found in select element`);
|
|
@@ -60,16 +63,16 @@ async function scrollIntoViewIfNeeded(e) {
|
|
|
60
63
|
const n = e;
|
|
61
64
|
n.scrollIntoViewIfNeeded ? n.scrollIntoViewIfNeeded() : n.scrollIntoView({ behavior: "auto", block: "center", inline: "nearest" });
|
|
62
65
|
}
|
|
63
|
-
async function scrollVertically(e, n,
|
|
64
|
-
if (
|
|
65
|
-
const l =
|
|
66
|
+
async function scrollVertically(e, n, i) {
|
|
67
|
+
if (i) {
|
|
68
|
+
const l = i;
|
|
66
69
|
console.log(
|
|
67
70
|
"[SCROLL DEBUG] Starting direct container scroll for element:",
|
|
68
71
|
l.tagName
|
|
69
72
|
);
|
|
70
|
-
let h = l, T = !1, b = null, u = 0,
|
|
71
|
-
const
|
|
72
|
-
for (; h &&
|
|
73
|
+
let h = l, T = !1, b = null, u = 0, g = 0;
|
|
74
|
+
const S = n;
|
|
75
|
+
for (; h && g < 10; ) {
|
|
73
76
|
const D = window.getComputedStyle(h), z = /(auto|scroll|overlay)/.test(D.overflowY), _ = h.scrollHeight > h.clientHeight;
|
|
74
77
|
if (console.log(
|
|
75
78
|
"[SCROLL DEBUG] Checking element:",
|
|
@@ -83,66 +86,66 @@ async function scrollVertically(e, n, s) {
|
|
|
83
86
|
"clientHeight:",
|
|
84
87
|
h.clientHeight
|
|
85
88
|
), z && _) {
|
|
86
|
-
const
|
|
87
|
-
let
|
|
88
|
-
|
|
89
|
-
const
|
|
89
|
+
const H = h.scrollTop, U = h.scrollHeight - h.clientHeight;
|
|
90
|
+
let R = S / 3;
|
|
91
|
+
R > 0 ? R = Math.min(R, U - H) : R = Math.max(R, -H), h.scrollTop = H + R;
|
|
92
|
+
const W = h.scrollTop, B = W - H;
|
|
90
93
|
if (console.log(
|
|
91
94
|
"[SCROLL DEBUG] Scroll attempt:",
|
|
92
95
|
h.tagName,
|
|
93
96
|
"before:",
|
|
94
|
-
|
|
97
|
+
H,
|
|
95
98
|
"after:",
|
|
96
|
-
|
|
99
|
+
W,
|
|
97
100
|
"delta:",
|
|
98
|
-
|
|
99
|
-
), Math.abs(
|
|
100
|
-
T = !0, b = h, u =
|
|
101
|
+
B
|
|
102
|
+
), Math.abs(B) > 0.5) {
|
|
103
|
+
T = !0, b = h, u = B, console.log(
|
|
101
104
|
"[SCROLL DEBUG] Successfully scrolled container:",
|
|
102
105
|
h.tagName,
|
|
103
106
|
"delta:",
|
|
104
|
-
|
|
107
|
+
B
|
|
105
108
|
);
|
|
106
109
|
break;
|
|
107
110
|
}
|
|
108
111
|
}
|
|
109
112
|
if (h === document.body || h === document.documentElement)
|
|
110
113
|
break;
|
|
111
|
-
h = h.parentElement,
|
|
114
|
+
h = h.parentElement, g++;
|
|
112
115
|
}
|
|
113
116
|
return T ? `Scrolled container (${b == null ? void 0 : b.tagName}) by ${u}px` : `No scrollable container found for element (${l.tagName})`;
|
|
114
117
|
}
|
|
115
|
-
const o = n,
|
|
116
|
-
let
|
|
117
|
-
for (;
|
|
118
|
-
if (
|
|
118
|
+
const o = n, f = (l) => l.clientHeight >= window.innerHeight * 0.5, d = (l) => l && /(auto|scroll|overlay)/.test(getComputedStyle(l).overflowY) && l.scrollHeight > l.clientHeight && f(l);
|
|
119
|
+
let s = document.activeElement;
|
|
120
|
+
for (; s && !d(s) && s !== document.body; ) s = s.parentElement;
|
|
121
|
+
if (s = d(s) ? s : Array.from(document.querySelectorAll("*")).find(d) || document.scrollingElement || document.documentElement, s === document.scrollingElement || s === document.documentElement || s === document.body) {
|
|
119
122
|
const l = window.scrollY, h = document.documentElement.scrollHeight - window.innerHeight;
|
|
120
123
|
window.scrollBy(0, o);
|
|
121
124
|
const T = window.scrollY, b = T - l;
|
|
122
125
|
if (Math.abs(b) < 1)
|
|
123
126
|
return o > 0 ? "⚠️ Already at the bottom of the page, cannot scroll down further." : "⚠️ Already at the top of the page, cannot scroll up further.";
|
|
124
|
-
const u = o > 0 && T >= h - 1,
|
|
125
|
-
return u ? `✅ Scrolled page by ${b}px. Reached the bottom of the page.` :
|
|
127
|
+
const u = o > 0 && T >= h - 1, g = o < 0 && T <= 1;
|
|
128
|
+
return u ? `✅ Scrolled page by ${b}px. Reached the bottom of the page.` : g ? `✅ Scrolled page by ${b}px. Reached the top of the page.` : `✅ Scrolled page by ${b}px.`;
|
|
126
129
|
} else {
|
|
127
|
-
const l =
|
|
128
|
-
|
|
129
|
-
const T =
|
|
130
|
+
const l = s.scrollTop, h = s.scrollHeight - s.clientHeight;
|
|
131
|
+
s.scrollBy({ top: o, behavior: "smooth" }), await waitFor(0.1);
|
|
132
|
+
const T = s.scrollTop, b = T - l;
|
|
130
133
|
if (Math.abs(b) < 1)
|
|
131
|
-
return o > 0 ? `⚠️ Already at the bottom of container (${
|
|
132
|
-
const u = o > 0 && T >= h - 1,
|
|
133
|
-
return u ? `✅ Scrolled container (${
|
|
134
|
+
return o > 0 ? `⚠️ Already at the bottom of container (${s.tagName}), cannot scroll down further.` : `⚠️ Already at the top of container (${s.tagName}), cannot scroll up further.`;
|
|
135
|
+
const u = o > 0 && T >= h - 1, g = o < 0 && T <= 1;
|
|
136
|
+
return u ? `✅ Scrolled container (${s.tagName}) by ${b}px. Reached the bottom.` : g ? `✅ Scrolled container (${s.tagName}) by ${b}px. Reached the top.` : `✅ Scrolled container (${s.tagName}) by ${b}px.`;
|
|
134
137
|
}
|
|
135
138
|
}
|
|
136
|
-
async function scrollHorizontally(e, n,
|
|
137
|
-
if (
|
|
138
|
-
const l =
|
|
139
|
+
async function scrollHorizontally(e, n, i) {
|
|
140
|
+
if (i) {
|
|
141
|
+
const l = i;
|
|
139
142
|
console.log(
|
|
140
143
|
"[SCROLL DEBUG] Starting direct container scroll for element:",
|
|
141
144
|
l.tagName
|
|
142
145
|
);
|
|
143
|
-
let h = l, T = !1, b = null, u = 0,
|
|
144
|
-
const
|
|
145
|
-
for (; h &&
|
|
146
|
+
let h = l, T = !1, b = null, u = 0, g = 0;
|
|
147
|
+
const S = e ? n : -n;
|
|
148
|
+
for (; h && g < 10; ) {
|
|
146
149
|
const D = window.getComputedStyle(h), z = /(auto|scroll|overlay)/.test(D.overflowX), _ = h.scrollWidth > h.clientWidth;
|
|
147
150
|
if (console.log(
|
|
148
151
|
"[SCROLL DEBUG] Checking element:",
|
|
@@ -156,54 +159,54 @@ async function scrollHorizontally(e, n, s) {
|
|
|
156
159
|
"clientWidth:",
|
|
157
160
|
h.clientWidth
|
|
158
161
|
), z && _) {
|
|
159
|
-
const
|
|
160
|
-
let
|
|
161
|
-
|
|
162
|
-
const
|
|
162
|
+
const H = h.scrollLeft, U = h.scrollWidth - h.clientWidth;
|
|
163
|
+
let R = S / 3;
|
|
164
|
+
R > 0 ? R = Math.min(R, U - H) : R = Math.max(R, -H), h.scrollLeft = H + R;
|
|
165
|
+
const W = h.scrollLeft, B = W - H;
|
|
163
166
|
if (console.log(
|
|
164
167
|
"[SCROLL DEBUG] Scroll attempt:",
|
|
165
168
|
h.tagName,
|
|
166
169
|
"before:",
|
|
167
|
-
|
|
170
|
+
H,
|
|
168
171
|
"after:",
|
|
169
|
-
|
|
172
|
+
W,
|
|
170
173
|
"delta:",
|
|
171
|
-
|
|
172
|
-
), Math.abs(
|
|
173
|
-
T = !0, b = h, u =
|
|
174
|
+
B
|
|
175
|
+
), Math.abs(B) > 0.5) {
|
|
176
|
+
T = !0, b = h, u = B, console.log(
|
|
174
177
|
"[SCROLL DEBUG] Successfully scrolled container:",
|
|
175
178
|
h.tagName,
|
|
176
179
|
"delta:",
|
|
177
|
-
|
|
180
|
+
B
|
|
178
181
|
);
|
|
179
182
|
break;
|
|
180
183
|
}
|
|
181
184
|
}
|
|
182
185
|
if (h === document.body || h === document.documentElement)
|
|
183
186
|
break;
|
|
184
|
-
h = h.parentElement,
|
|
187
|
+
h = h.parentElement, g++;
|
|
185
188
|
}
|
|
186
189
|
return T ? `Scrolled container (${b == null ? void 0 : b.tagName}) horizontally by ${u}px` : `No horizontally scrollable container found for element (${l.tagName})`;
|
|
187
190
|
}
|
|
188
|
-
const o = e ? n : -n,
|
|
189
|
-
let
|
|
190
|
-
for (;
|
|
191
|
-
if (
|
|
191
|
+
const o = e ? n : -n, f = (l) => l.clientWidth >= window.innerWidth * 0.5, d = (l) => l && /(auto|scroll|overlay)/.test(getComputedStyle(l).overflowX) && l.scrollWidth > l.clientWidth && f(l);
|
|
192
|
+
let s = document.activeElement;
|
|
193
|
+
for (; s && !d(s) && s !== document.body; ) s = s.parentElement;
|
|
194
|
+
if (s = d(s) ? s : Array.from(document.querySelectorAll("*")).find(d) || document.scrollingElement || document.documentElement, s === document.scrollingElement || s === document.documentElement || s === document.body) {
|
|
192
195
|
const l = window.scrollX, h = document.documentElement.scrollWidth - window.innerWidth;
|
|
193
196
|
window.scrollBy(o, 0);
|
|
194
197
|
const T = window.scrollX, b = T - l;
|
|
195
198
|
if (Math.abs(b) < 1)
|
|
196
199
|
return o > 0 ? "⚠️ Already at the right edge of the page, cannot scroll right further." : "⚠️ Already at the left edge of the page, cannot scroll left further.";
|
|
197
|
-
const u = o > 0 && T >= h - 1,
|
|
198
|
-
return u ? `✅ Scrolled page by ${b}px. Reached the right edge of the page.` :
|
|
200
|
+
const u = o > 0 && T >= h - 1, g = o < 0 && T <= 1;
|
|
201
|
+
return u ? `✅ Scrolled page by ${b}px. Reached the right edge of the page.` : g ? `✅ Scrolled page by ${b}px. Reached the left edge of the page.` : `✅ Scrolled page horizontally by ${b}px.`;
|
|
199
202
|
} else {
|
|
200
|
-
const l =
|
|
201
|
-
|
|
202
|
-
const T =
|
|
203
|
+
const l = s.scrollLeft, h = s.scrollWidth - s.clientWidth;
|
|
204
|
+
s.scrollBy({ left: o, behavior: "smooth" }), await waitFor(0.1);
|
|
205
|
+
const T = s.scrollLeft, b = T - l;
|
|
203
206
|
if (Math.abs(b) < 1)
|
|
204
|
-
return o > 0 ? `⚠️ Already at the right edge of container (${
|
|
205
|
-
const u = o > 0 && T >= h - 1,
|
|
206
|
-
return u ? `✅ Scrolled container (${
|
|
207
|
+
return o > 0 ? `⚠️ Already at the right edge of container (${s.tagName}), cannot scroll right further.` : `⚠️ Already at the left edge of container (${s.tagName}), cannot scroll left further.`;
|
|
208
|
+
const u = o > 0 && T >= h - 1, g = o < 0 && T <= 1;
|
|
209
|
+
return u ? `✅ Scrolled container (${s.tagName}) by ${b}px. Reached the right edge.` : g ? `✅ Scrolled container (${s.tagName}) by ${b}px. Reached the left edge.` : `✅ Scrolled container (${s.tagName}) horizontally by ${b}px.`;
|
|
207
210
|
}
|
|
208
211
|
}
|
|
209
212
|
const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
@@ -221,52 +224,52 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
221
224
|
highlightOpacity: 0.1,
|
|
222
225
|
highlightLabelOpacity: 0.5
|
|
223
226
|
}) => {
|
|
224
|
-
const { interactiveBlacklist: n, interactiveWhitelist:
|
|
227
|
+
const { interactiveBlacklist: n, interactiveWhitelist: i, highlightOpacity: o, highlightLabelOpacity: f } = e, { doHighlightElements: d, focusHighlightIndex: s, viewportExpansion: l, debugMode: h } = e;
|
|
225
228
|
let T = 0;
|
|
226
229
|
const b = /* @__PURE__ */ new WeakMap();
|
|
227
|
-
function u(t,
|
|
228
|
-
!t || t.nodeType !== Node.ELEMENT_NODE || b.set(t, { ...b.get(t), ...
|
|
230
|
+
function u(t, r) {
|
|
231
|
+
!t || t.nodeType !== Node.ELEMENT_NODE || b.set(t, { ...b.get(t), ...r });
|
|
229
232
|
}
|
|
230
|
-
const
|
|
233
|
+
const g = {
|
|
231
234
|
boundingRects: /* @__PURE__ */ new WeakMap(),
|
|
232
235
|
clientRects: /* @__PURE__ */ new WeakMap(),
|
|
233
236
|
computedStyles: /* @__PURE__ */ new WeakMap(),
|
|
234
237
|
clearCache: () => {
|
|
235
|
-
|
|
238
|
+
g.boundingRects = /* @__PURE__ */ new WeakMap(), g.clientRects = /* @__PURE__ */ new WeakMap(), g.computedStyles = /* @__PURE__ */ new WeakMap();
|
|
236
239
|
}
|
|
237
240
|
};
|
|
238
|
-
function
|
|
241
|
+
function S(t) {
|
|
239
242
|
if (!t) return null;
|
|
240
|
-
if (
|
|
241
|
-
return
|
|
242
|
-
const
|
|
243
|
-
return
|
|
243
|
+
if (g.boundingRects.has(t))
|
|
244
|
+
return g.boundingRects.get(t);
|
|
245
|
+
const r = t.getBoundingClientRect();
|
|
246
|
+
return r && g.boundingRects.set(t, r), r;
|
|
244
247
|
}
|
|
245
248
|
function D(t) {
|
|
246
249
|
if (!t) return null;
|
|
247
|
-
if (
|
|
248
|
-
return
|
|
249
|
-
const
|
|
250
|
-
return
|
|
250
|
+
if (g.computedStyles.has(t))
|
|
251
|
+
return g.computedStyles.get(t);
|
|
252
|
+
const r = window.getComputedStyle(t);
|
|
253
|
+
return r && g.computedStyles.set(t, r), r;
|
|
251
254
|
}
|
|
252
255
|
function z(t) {
|
|
253
256
|
if (!t) return null;
|
|
254
|
-
if (
|
|
255
|
-
return
|
|
256
|
-
const
|
|
257
|
-
return
|
|
257
|
+
if (g.clientRects.has(t))
|
|
258
|
+
return g.clientRects.get(t);
|
|
259
|
+
const r = t.getClientRects();
|
|
260
|
+
return r && g.clientRects.set(t, r), r;
|
|
258
261
|
}
|
|
259
|
-
const _ = {},
|
|
260
|
-
function
|
|
261
|
-
if (!t) return
|
|
262
|
+
const _ = {}, H = { current: 0 }, U = "playwright-highlight-container";
|
|
263
|
+
function R(t, r, m = null) {
|
|
264
|
+
if (!t) return r;
|
|
262
265
|
const c = [];
|
|
263
266
|
let a = null, x = 20, E = 16, I = null;
|
|
264
267
|
try {
|
|
265
|
-
let
|
|
266
|
-
|
|
267
|
-
const
|
|
268
|
-
if (
|
|
269
|
-
const
|
|
268
|
+
let w = document.getElementById(U);
|
|
269
|
+
w || (w = document.createElement("div"), w.id = U, w.style.position = "fixed", w.style.pointerEvents = "none", w.style.top = "0", w.style.left = "0", w.style.width = "100%", w.style.height = "100%", w.style.zIndex = "2147483640", w.style.backgroundColor = "transparent", document.body.appendChild(w));
|
|
270
|
+
const $ = t.getClientRects();
|
|
271
|
+
if (!$ || $.length === 0) return r;
|
|
272
|
+
const A = [
|
|
270
273
|
"#FF0000",
|
|
271
274
|
"#00FF00",
|
|
272
275
|
"#0000FF",
|
|
@@ -279,94 +282,94 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
279
282
|
"#2E8B57",
|
|
280
283
|
"#DC143C",
|
|
281
284
|
"#4682B4"
|
|
282
|
-
],
|
|
283
|
-
let y =
|
|
284
|
-
const
|
|
285
|
-
y = y + Math.floor(
|
|
286
|
-
let
|
|
287
|
-
if (
|
|
288
|
-
const
|
|
289
|
-
|
|
285
|
+
], p = r % A.length;
|
|
286
|
+
let y = A[p];
|
|
287
|
+
const M = y + Math.floor(o * 255).toString(16).padStart(2, "0");
|
|
288
|
+
y = y + Math.floor(f * 255).toString(16).padStart(2, "0");
|
|
289
|
+
let C = { x: 0, y: 0 };
|
|
290
|
+
if (m) {
|
|
291
|
+
const k = m.getBoundingClientRect();
|
|
292
|
+
C.x = k.left, C.y = k.top;
|
|
290
293
|
}
|
|
291
|
-
const
|
|
292
|
-
for (const
|
|
293
|
-
if (
|
|
294
|
-
const
|
|
295
|
-
|
|
296
|
-
const v =
|
|
297
|
-
|
|
294
|
+
const V = document.createDocumentFragment();
|
|
295
|
+
for (const k of $) {
|
|
296
|
+
if (k.width === 0 || k.height === 0) continue;
|
|
297
|
+
const N = document.createElement("div");
|
|
298
|
+
N.style.position = "fixed", N.style.border = `2px solid ${y}`, N.style.backgroundColor = M, N.style.pointerEvents = "none", N.style.boxSizing = "border-box";
|
|
299
|
+
const v = k.top + C.y, F = k.left + C.x;
|
|
300
|
+
N.style.top = `${v}px`, N.style.left = `${F}px`, N.style.width = `${k.width}px`, N.style.height = `${k.height}px`, V.appendChild(N), c.push({ element: N, initialRect: k });
|
|
298
301
|
}
|
|
299
|
-
const G =
|
|
300
|
-
if (
|
|
301
|
-
a = document.createElement("div"), a.className = "playwright-highlight-label", a.style.position = "fixed", a.style.background = y, a.style.color = "white", a.style.padding = "1px 4px", a.style.borderRadius = "4px", a.style.fontSize = `${Math.min(12, Math.max(8, G.height / 2))}px`, a.textContent =
|
|
302
|
-
const
|
|
303
|
-
let v =
|
|
304
|
-
(G.width < x + 4 || G.height < E + 4) && (v =
|
|
302
|
+
const G = $[0];
|
|
303
|
+
if (f > 0) {
|
|
304
|
+
a = document.createElement("div"), a.className = "playwright-highlight-label", a.style.position = "fixed", a.style.background = y, a.style.color = "white", a.style.padding = "1px 4px", a.style.borderRadius = "4px", a.style.fontSize = `${Math.min(12, Math.max(8, G.height / 2))}px`, a.textContent = r.toString(), x = a.offsetWidth > 0 ? a.offsetWidth : x, E = a.offsetHeight > 0 ? a.offsetHeight : E;
|
|
305
|
+
const k = G.top + C.y, N = G.left + C.x;
|
|
306
|
+
let v = k + 2, F = N + G.width - x - 2;
|
|
307
|
+
(G.width < x + 4 || G.height < E + 4) && (v = k - E - 2, F = N + G.width - x, F < C.x && (F = N)), v = Math.max(0, Math.min(v, window.innerHeight - E)), F = Math.max(0, Math.min(F, window.innerWidth - x)), a.style.top = `${v}px`, a.style.left = `${F}px`, V.appendChild(a);
|
|
305
308
|
}
|
|
306
|
-
const j = ((
|
|
309
|
+
const j = ((k, N) => {
|
|
307
310
|
let v = 0;
|
|
308
|
-
return (...
|
|
311
|
+
return (...F) => {
|
|
309
312
|
const P = performance.now();
|
|
310
|
-
if (!(P - v <
|
|
311
|
-
return v = P,
|
|
313
|
+
if (!(P - v < N))
|
|
314
|
+
return v = P, k(...F);
|
|
312
315
|
};
|
|
313
316
|
})(() => {
|
|
314
|
-
const
|
|
315
|
-
let
|
|
316
|
-
if (
|
|
317
|
-
const v =
|
|
318
|
-
|
|
317
|
+
const k = t.getClientRects();
|
|
318
|
+
let N = { x: 0, y: 0 };
|
|
319
|
+
if (m) {
|
|
320
|
+
const v = m.getBoundingClientRect();
|
|
321
|
+
N.x = v.left, N.y = v.top;
|
|
319
322
|
}
|
|
320
|
-
if (c.forEach((v,
|
|
321
|
-
if (
|
|
322
|
-
const P =
|
|
323
|
-
v.element.style.top = `${Z}px`, v.element.style.left = `${
|
|
323
|
+
if (c.forEach((v, F) => {
|
|
324
|
+
if (F < k.length) {
|
|
325
|
+
const P = k[F], Z = P.top + N.y, K = P.left + N.x;
|
|
326
|
+
v.element.style.top = `${Z}px`, v.element.style.left = `${K}px`, v.element.style.width = `${P.width}px`, v.element.style.height = `${P.height}px`, v.element.style.display = P.width === 0 || P.height === 0 ? "none" : "block";
|
|
324
327
|
} else
|
|
325
328
|
v.element.style.display = "none";
|
|
326
|
-
}),
|
|
327
|
-
for (let v =
|
|
329
|
+
}), k.length < c.length)
|
|
330
|
+
for (let v = k.length; v < c.length; v++)
|
|
328
331
|
c[v].element.style.display = "none";
|
|
329
|
-
if (a &&
|
|
330
|
-
const v =
|
|
331
|
-
let Z =
|
|
332
|
-
(v.width < x + 4 || v.height < E + 4) && (Z =
|
|
332
|
+
if (a && k.length > 0) {
|
|
333
|
+
const v = k[0], F = v.top + N.y, P = v.left + N.x;
|
|
334
|
+
let Z = F + 2, K = P + v.width - x - 2;
|
|
335
|
+
(v.width < x + 4 || v.height < E + 4) && (Z = F - E - 2, K = P + v.width - x, K < N.x && (K = P)), Z = Math.max(0, Math.min(Z, window.innerHeight - E)), K = Math.max(0, Math.min(K, window.innerWidth - x)), a.style.top = `${Z}px`, a.style.left = `${K}px`, a.style.display = "block";
|
|
333
336
|
} else a && (a.style.display = "none");
|
|
334
337
|
}, 16);
|
|
335
338
|
return window.addEventListener("scroll", j, !0), window.addEventListener("resize", j), I = () => {
|
|
336
|
-
window.removeEventListener("scroll", j, !0), window.removeEventListener("resize", j), c.forEach((
|
|
337
|
-
},
|
|
339
|
+
window.removeEventListener("scroll", j, !0), window.removeEventListener("resize", j), c.forEach((k) => k.element.remove()), a && a.remove();
|
|
340
|
+
}, w.appendChild(V), r + 1;
|
|
338
341
|
} finally {
|
|
339
342
|
I && (window._highlightCleanupFunctions = window._highlightCleanupFunctions || []).push(
|
|
340
343
|
I
|
|
341
344
|
);
|
|
342
345
|
}
|
|
343
346
|
}
|
|
344
|
-
function
|
|
347
|
+
function W(t) {
|
|
345
348
|
if (!t || t.nodeType !== Node.ELEMENT_NODE)
|
|
346
349
|
return null;
|
|
347
|
-
const
|
|
348
|
-
if (!
|
|
349
|
-
const
|
|
350
|
-
if (
|
|
350
|
+
const r = D(t);
|
|
351
|
+
if (!r) return null;
|
|
352
|
+
const m = r.display;
|
|
353
|
+
if (m === "inline" || m === "inline-block")
|
|
351
354
|
return null;
|
|
352
|
-
const c =
|
|
355
|
+
const c = r.overflowX, a = r.overflowY, x = c === "auto" || c === "scroll", E = a === "auto" || a === "scroll";
|
|
353
356
|
if (!x && !E)
|
|
354
357
|
return null;
|
|
355
|
-
const I = t.scrollWidth - t.clientWidth,
|
|
356
|
-
if (I <
|
|
358
|
+
const I = t.scrollWidth - t.clientWidth, w = t.scrollHeight - t.clientHeight, $ = 4;
|
|
359
|
+
if (I < $ && w < $ || !E && I < $ || !x && w < $)
|
|
357
360
|
return null;
|
|
358
|
-
const
|
|
359
|
-
top:
|
|
361
|
+
const A = t.scrollTop, p = t.scrollLeft, y = t.scrollWidth - t.clientWidth - t.scrollLeft, M = t.scrollHeight - t.clientHeight - t.scrollTop, C = {
|
|
362
|
+
top: A,
|
|
360
363
|
right: y,
|
|
361
|
-
bottom:
|
|
362
|
-
left:
|
|
364
|
+
bottom: M,
|
|
365
|
+
left: p
|
|
363
366
|
};
|
|
364
367
|
return u(t, {
|
|
365
368
|
scrollable: !0,
|
|
366
|
-
scrollData:
|
|
367
|
-
}),
|
|
369
|
+
scrollData: C
|
|
370
|
+
}), C;
|
|
368
371
|
}
|
|
369
|
-
function
|
|
372
|
+
function B(t) {
|
|
370
373
|
try {
|
|
371
374
|
if (l === -1) {
|
|
372
375
|
const E = t.parentElement;
|
|
@@ -377,17 +380,17 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
377
380
|
checkVisibilityCSS: !0
|
|
378
381
|
});
|
|
379
382
|
} catch {
|
|
380
|
-
const
|
|
381
|
-
return
|
|
383
|
+
const w = window.getComputedStyle(E);
|
|
384
|
+
return w.display !== "none" && w.visibility !== "hidden" && w.opacity !== "0";
|
|
382
385
|
}
|
|
383
386
|
}
|
|
384
|
-
const
|
|
385
|
-
|
|
386
|
-
const
|
|
387
|
-
if (!
|
|
387
|
+
const r = document.createRange();
|
|
388
|
+
r.selectNodeContents(t);
|
|
389
|
+
const m = r.getClientRects();
|
|
390
|
+
if (!m || m.length === 0)
|
|
388
391
|
return !1;
|
|
389
392
|
let c = !1, a = !1;
|
|
390
|
-
for (const E of
|
|
393
|
+
for (const E of m)
|
|
391
394
|
if (E.width > 0 && E.height > 0 && (c = !0, !(E.bottom < -l || E.top > window.innerHeight + l || E.right < -l || E.left > window.innerWidth + l))) {
|
|
392
395
|
a = !0;
|
|
393
396
|
break;
|
|
@@ -405,13 +408,13 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
405
408
|
const I = window.getComputedStyle(x);
|
|
406
409
|
return I.display !== "none" && I.visibility !== "hidden" && I.opacity !== "0";
|
|
407
410
|
}
|
|
408
|
-
} catch (
|
|
409
|
-
return console.warn("Error checking text node visibility:",
|
|
411
|
+
} catch (r) {
|
|
412
|
+
return console.warn("Error checking text node visibility:", r), !1;
|
|
410
413
|
}
|
|
411
414
|
}
|
|
412
415
|
function it(t) {
|
|
413
416
|
if (!t || !t.tagName) return !1;
|
|
414
|
-
const
|
|
417
|
+
const r = /* @__PURE__ */ new Set([
|
|
415
418
|
"body",
|
|
416
419
|
"div",
|
|
417
420
|
"main",
|
|
@@ -420,8 +423,8 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
420
423
|
"nav",
|
|
421
424
|
"header",
|
|
422
425
|
"footer"
|
|
423
|
-
]),
|
|
424
|
-
return
|
|
426
|
+
]), m = t.tagName.toLowerCase();
|
|
427
|
+
return r.has(m) ? !0 : !(/* @__PURE__ */ new Set([
|
|
425
428
|
"svg",
|
|
426
429
|
"script",
|
|
427
430
|
"style",
|
|
@@ -429,19 +432,19 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
429
432
|
"meta",
|
|
430
433
|
"noscript",
|
|
431
434
|
"template"
|
|
432
|
-
])).has(
|
|
435
|
+
])).has(m);
|
|
433
436
|
}
|
|
434
437
|
function X(t) {
|
|
435
|
-
const
|
|
436
|
-
return t.offsetWidth > 0 && t.offsetHeight > 0 && (
|
|
438
|
+
const r = D(t);
|
|
439
|
+
return t.offsetWidth > 0 && t.offsetHeight > 0 && (r == null ? void 0 : r.visibility) !== "hidden" && (r == null ? void 0 : r.display) !== "none";
|
|
437
440
|
}
|
|
438
441
|
function L(t) {
|
|
439
|
-
var
|
|
442
|
+
var M, C;
|
|
440
443
|
if (!t || t.nodeType !== Node.ELEMENT_NODE || n.includes(t))
|
|
441
444
|
return !1;
|
|
442
|
-
if (
|
|
445
|
+
if (i.includes(t))
|
|
443
446
|
return !0;
|
|
444
|
-
const
|
|
447
|
+
const r = t.tagName.toLowerCase(), m = D(t), c = /* @__PURE__ */ new Set([
|
|
445
448
|
"pointer",
|
|
446
449
|
// Link/clickable elements
|
|
447
450
|
"move",
|
|
@@ -518,8 +521,8 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
518
521
|
// 'default', // Default cursor
|
|
519
522
|
// 'auto', // Browser default
|
|
520
523
|
]);
|
|
521
|
-
function x(
|
|
522
|
-
return
|
|
524
|
+
function x(V) {
|
|
525
|
+
return V.tagName.toLowerCase() === "html" ? !1 : !!(m != null && m.cursor && c.has(m.cursor));
|
|
523
526
|
}
|
|
524
527
|
if (x(t))
|
|
525
528
|
return !0;
|
|
@@ -548,7 +551,7 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
548
551
|
// Form fieldsets (can be interactive with legend)
|
|
549
552
|
"legend"
|
|
550
553
|
// Fieldset legends
|
|
551
|
-
]),
|
|
554
|
+
]), w = /* @__PURE__ */ new Set([
|
|
552
555
|
"disabled",
|
|
553
556
|
// Standard disabled attribute
|
|
554
557
|
// 'aria-disabled', // ARIA disabled state
|
|
@@ -562,18 +565,18 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
562
565
|
// 'tabindex="-1"', // Removed from tab order
|
|
563
566
|
// 'aria-hidden="true"' // Hidden from screen readers
|
|
564
567
|
]);
|
|
565
|
-
if (I.has(
|
|
566
|
-
if (
|
|
568
|
+
if (I.has(r)) {
|
|
569
|
+
if (m != null && m.cursor && a.has(m.cursor))
|
|
567
570
|
return !1;
|
|
568
|
-
for (const
|
|
569
|
-
if (t.hasAttribute(
|
|
571
|
+
for (const V of w)
|
|
572
|
+
if (t.hasAttribute(V) || t.getAttribute(V) === "true" || t.getAttribute(V) === "")
|
|
570
573
|
return !1;
|
|
571
574
|
return !(t.disabled || t.readOnly || t.inert);
|
|
572
575
|
}
|
|
573
|
-
const
|
|
576
|
+
const $ = t.getAttribute("role"), A = t.getAttribute("aria-role");
|
|
574
577
|
if (t.getAttribute("contenteditable") === "true" || t.isContentEditable || t.classList && (t.classList.contains("button") || t.classList.contains("dropdown-toggle") || t.getAttribute("data-index") || t.getAttribute("data-toggle") === "dropdown" || t.getAttribute("aria-haspopup") === "true"))
|
|
575
578
|
return !0;
|
|
576
|
-
const
|
|
579
|
+
const p = /* @__PURE__ */ new Set([
|
|
577
580
|
"button",
|
|
578
581
|
// Directly clickable element
|
|
579
582
|
// 'link', // Clickable link
|
|
@@ -612,7 +615,7 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
612
615
|
"scrollbar"
|
|
613
616
|
// Scrollable control
|
|
614
617
|
]);
|
|
615
|
-
if (I.has(
|
|
618
|
+
if (I.has(r) || $ && p.has($) || A && p.has(A)) return !0;
|
|
616
619
|
try {
|
|
617
620
|
if (typeof getEventListeners == "function") {
|
|
618
621
|
const q = getEventListeners(t), nt = ["click", "mousedown", "mouseup", "dblclick"];
|
|
@@ -620,9 +623,9 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
620
623
|
if (q[j] && q[j].length > 0)
|
|
621
624
|
return !0;
|
|
622
625
|
}
|
|
623
|
-
const
|
|
624
|
-
if (typeof
|
|
625
|
-
const q =
|
|
626
|
+
const V = ((C = (M = t == null ? void 0 : t.ownerDocument) == null ? void 0 : M.defaultView) == null ? void 0 : C.getEventListenersForNode) || window.getEventListenersForNode;
|
|
627
|
+
if (typeof V == "function") {
|
|
628
|
+
const q = V(t), nt = [
|
|
626
629
|
"click",
|
|
627
630
|
"mousedown",
|
|
628
631
|
"mouseup",
|
|
@@ -635,8 +638,8 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
635
638
|
"blur"
|
|
636
639
|
];
|
|
637
640
|
for (const j of nt)
|
|
638
|
-
for (const
|
|
639
|
-
if (
|
|
641
|
+
for (const k of q)
|
|
642
|
+
if (k.type === j)
|
|
640
643
|
return !0;
|
|
641
644
|
}
|
|
642
645
|
const G = ["onclick", "onmousedown", "onmouseup", "ondblclick"];
|
|
@@ -645,38 +648,38 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
645
648
|
return !0;
|
|
646
649
|
} catch {
|
|
647
650
|
}
|
|
648
|
-
return !!
|
|
651
|
+
return !!W(t);
|
|
649
652
|
}
|
|
650
653
|
function et(t) {
|
|
651
654
|
if (l === -1)
|
|
652
655
|
return !0;
|
|
653
|
-
const
|
|
654
|
-
if (!
|
|
656
|
+
const r = z(t);
|
|
657
|
+
if (!r || r.length === 0)
|
|
655
658
|
return !1;
|
|
656
|
-
let
|
|
657
|
-
for (const
|
|
658
|
-
if (
|
|
659
|
-
(
|
|
660
|
-
|
|
659
|
+
let m = !1;
|
|
660
|
+
for (const w of r)
|
|
661
|
+
if (w.width > 0 && w.height > 0 && !// Only check non-empty rects
|
|
662
|
+
(w.bottom < -l || w.top > window.innerHeight + l || w.right < -l || w.left > window.innerWidth + l)) {
|
|
663
|
+
m = !0;
|
|
661
664
|
break;
|
|
662
665
|
}
|
|
663
|
-
if (!
|
|
666
|
+
if (!m)
|
|
664
667
|
return !1;
|
|
665
668
|
if (t.ownerDocument !== window.document)
|
|
666
669
|
return !0;
|
|
667
|
-
let a = Array.from(
|
|
670
|
+
let a = Array.from(r).find((w) => w.width > 0 && w.height > 0);
|
|
668
671
|
if (!a)
|
|
669
672
|
return !1;
|
|
670
673
|
const x = t.getRootNode();
|
|
671
674
|
if (x instanceof ShadowRoot) {
|
|
672
|
-
const
|
|
675
|
+
const w = a.left + a.width / 2, $ = a.top + a.height / 2;
|
|
673
676
|
try {
|
|
674
|
-
const
|
|
675
|
-
if (
|
|
676
|
-
let
|
|
677
|
-
for (;
|
|
678
|
-
if (
|
|
679
|
-
|
|
677
|
+
const A = x.elementFromPoint(w, $);
|
|
678
|
+
if (!A) return !1;
|
|
679
|
+
let p = A;
|
|
680
|
+
for (; p && p !== x; ) {
|
|
681
|
+
if (p === t) return !0;
|
|
682
|
+
p = p.parentElement;
|
|
680
683
|
}
|
|
681
684
|
return !1;
|
|
682
685
|
} catch {
|
|
@@ -693,14 +696,14 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
693
696
|
// { x: rect.left + margin, y: rect.bottom - margin }, // bottom left
|
|
694
697
|
{ x: a.right - E, y: a.bottom - E }
|
|
695
698
|
// bottom right
|
|
696
|
-
].some(({ x:
|
|
699
|
+
].some(({ x: w, y: $ }) => {
|
|
697
700
|
try {
|
|
698
|
-
const
|
|
699
|
-
if (
|
|
700
|
-
let
|
|
701
|
-
for (;
|
|
702
|
-
if (
|
|
703
|
-
|
|
701
|
+
const A = document.elementFromPoint(w, $);
|
|
702
|
+
if (!A) return !1;
|
|
703
|
+
let p = A;
|
|
704
|
+
for (; p && p !== document.documentElement; ) {
|
|
705
|
+
if (p === t) return !0;
|
|
706
|
+
p = p.parentElement;
|
|
704
707
|
}
|
|
705
708
|
return !1;
|
|
706
709
|
} catch {
|
|
@@ -708,22 +711,22 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
708
711
|
}
|
|
709
712
|
});
|
|
710
713
|
}
|
|
711
|
-
function ot(t,
|
|
712
|
-
if (
|
|
714
|
+
function ot(t, r) {
|
|
715
|
+
if (r === -1)
|
|
713
716
|
return !0;
|
|
714
|
-
const
|
|
715
|
-
if (!
|
|
716
|
-
const c =
|
|
717
|
-
return !c || c.width === 0 || c.height === 0 ? !1 : !(c.bottom < -
|
|
717
|
+
const m = t.getClientRects();
|
|
718
|
+
if (!m || m.length === 0) {
|
|
719
|
+
const c = S(t);
|
|
720
|
+
return !c || c.width === 0 || c.height === 0 ? !1 : !(c.bottom < -r || c.top > window.innerHeight + r || c.right < -r || c.left > window.innerWidth + r);
|
|
718
721
|
}
|
|
719
|
-
for (const c of
|
|
720
|
-
if (!(c.width === 0 || c.height === 0) && !(c.bottom < -
|
|
722
|
+
for (const c of m)
|
|
723
|
+
if (!(c.width === 0 || c.height === 0) && !(c.bottom < -r || c.top > window.innerHeight + r || c.right < -r || c.left > window.innerWidth + r))
|
|
721
724
|
return !0;
|
|
722
725
|
return !1;
|
|
723
726
|
}
|
|
724
|
-
function
|
|
727
|
+
function O(t) {
|
|
725
728
|
if (!t || t.nodeType !== Node.ELEMENT_NODE) return !1;
|
|
726
|
-
const
|
|
729
|
+
const r = t.tagName.toLowerCase();
|
|
727
730
|
return (/* @__PURE__ */ new Set([
|
|
728
731
|
"a",
|
|
729
732
|
"button",
|
|
@@ -733,7 +736,7 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
733
736
|
"details",
|
|
734
737
|
"summary",
|
|
735
738
|
"label"
|
|
736
|
-
])).has(
|
|
739
|
+
])).has(r) ? !0 : t.hasAttribute("onclick") || t.hasAttribute("role") || t.hasAttribute("tabindex") || t.hasAttribute("aria-") || t.hasAttribute("data-action") || t.getAttribute("contenteditable") === "true";
|
|
737
740
|
}
|
|
738
741
|
const Y = /* @__PURE__ */ new Set([
|
|
739
742
|
"a",
|
|
@@ -745,7 +748,7 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
745
748
|
"details",
|
|
746
749
|
"label",
|
|
747
750
|
"option"
|
|
748
|
-
]),
|
|
751
|
+
]), J = /* @__PURE__ */ new Set([
|
|
749
752
|
"button",
|
|
750
753
|
"link",
|
|
751
754
|
"menuitem",
|
|
@@ -766,22 +769,22 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
766
769
|
]);
|
|
767
770
|
function tt(t) {
|
|
768
771
|
if (!t || t.nodeType !== Node.ELEMENT_NODE || !X(t)) return !1;
|
|
769
|
-
const
|
|
772
|
+
const r = t.hasAttribute("role") || t.hasAttribute("tabindex") || t.hasAttribute("onclick") || typeof t.onclick == "function", m = /\b(btn|clickable|menu|item|entry|link)\b/i.test(
|
|
770
773
|
t.className || ""
|
|
771
774
|
), c = !!t.closest('button,a,[role="button"],.menu,.dropdown,.list,.toolbar'), a = [...t.children].some(X), x = t.parentElement && t.parentElement.isSameNode(document.body);
|
|
772
|
-
return (L(t) ||
|
|
775
|
+
return (L(t) || r || m) && a && c && !x;
|
|
773
776
|
}
|
|
774
777
|
function rt(t) {
|
|
775
778
|
var c, a;
|
|
776
779
|
if (!t || t.nodeType !== Node.ELEMENT_NODE)
|
|
777
780
|
return !1;
|
|
778
|
-
const
|
|
779
|
-
if (
|
|
781
|
+
const r = t.tagName.toLowerCase(), m = t.getAttribute("role");
|
|
782
|
+
if (r === "iframe" || Y.has(r) || m && J.has(m) || t.isContentEditable || t.getAttribute("contenteditable") === "true" || t.hasAttribute("data-testid") || t.hasAttribute("data-cy") || t.hasAttribute("data-test") || t.hasAttribute("onclick") || typeof t.onclick == "function")
|
|
780
783
|
return !0;
|
|
781
784
|
try {
|
|
782
785
|
const x = ((a = (c = t == null ? void 0 : t.ownerDocument) == null ? void 0 : c.defaultView) == null ? void 0 : a.getEventListenersForNode) || window.getEventListenersForNode;
|
|
783
786
|
if (typeof x == "function") {
|
|
784
|
-
const I = x(t),
|
|
787
|
+
const I = x(t), w = [
|
|
785
788
|
"click",
|
|
786
789
|
"mousedown",
|
|
787
790
|
"mouseup",
|
|
@@ -793,9 +796,9 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
793
796
|
"focus",
|
|
794
797
|
"blur"
|
|
795
798
|
];
|
|
796
|
-
for (const
|
|
797
|
-
for (const
|
|
798
|
-
if (
|
|
799
|
+
for (const $ of w)
|
|
800
|
+
for (const A of I)
|
|
801
|
+
if (A.type === $)
|
|
799
802
|
return !0;
|
|
800
803
|
}
|
|
801
804
|
if ([
|
|
@@ -814,50 +817,50 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
814
817
|
}
|
|
815
818
|
return !!tt(t);
|
|
816
819
|
}
|
|
817
|
-
function st(t,
|
|
820
|
+
function st(t, r, m, c) {
|
|
818
821
|
if (!t.isInteractive) return !1;
|
|
819
822
|
let a = !1;
|
|
820
|
-
return c ? rt(
|
|
823
|
+
return c ? rt(r) ? a = !0 : a = !1 : a = !0, a && (t.isInViewport = ot(r, l), (t.isInViewport || l === -1) && (t.highlightIndex = T++, d)) ? (s >= 0 ? s === t.highlightIndex && R(r, t.highlightIndex, m) : R(r, t.highlightIndex, m), !0) : !1;
|
|
821
824
|
}
|
|
822
|
-
function Q(t,
|
|
823
|
-
var E, I,
|
|
825
|
+
function Q(t, r = null, m = !1) {
|
|
826
|
+
var E, I, w, $, A;
|
|
824
827
|
if (!t || t.id === U || t.nodeType !== Node.ELEMENT_NODE && t.nodeType !== Node.TEXT_NODE || !t || t.id === U || ((E = t.dataset) == null ? void 0 : E.browserUseIgnore) === "true" || t.getAttribute && t.getAttribute("aria-hidden") === "true")
|
|
825
828
|
return null;
|
|
826
829
|
if (t === document.body) {
|
|
827
|
-
const
|
|
830
|
+
const p = {
|
|
828
831
|
tagName: "body",
|
|
829
832
|
attributes: {},
|
|
830
833
|
xpath: "/body",
|
|
831
834
|
children: []
|
|
832
835
|
};
|
|
833
|
-
for (const
|
|
834
|
-
const
|
|
835
|
-
|
|
836
|
+
for (const M of t.childNodes) {
|
|
837
|
+
const C = Q(M, r, !1);
|
|
838
|
+
C && p.children.push(C);
|
|
836
839
|
}
|
|
837
|
-
const y = `${
|
|
838
|
-
return _[y] =
|
|
840
|
+
const y = `${H.current++}`;
|
|
841
|
+
return _[y] = p, y;
|
|
839
842
|
}
|
|
840
843
|
if (t.nodeType !== Node.ELEMENT_NODE && t.nodeType !== Node.TEXT_NODE)
|
|
841
844
|
return null;
|
|
842
845
|
if (t.nodeType === Node.TEXT_NODE) {
|
|
843
|
-
const
|
|
844
|
-
if (!
|
|
846
|
+
const p = (I = t.textContent) == null ? void 0 : I.trim();
|
|
847
|
+
if (!p)
|
|
845
848
|
return null;
|
|
846
849
|
const y = t.parentElement;
|
|
847
850
|
if (!y || y.tagName.toLowerCase() === "script")
|
|
848
851
|
return null;
|
|
849
|
-
const
|
|
850
|
-
return _[
|
|
852
|
+
const M = `${H.current++}`;
|
|
853
|
+
return _[M] = {
|
|
851
854
|
type: "TEXT_NODE",
|
|
852
|
-
text:
|
|
853
|
-
isVisible:
|
|
854
|
-
},
|
|
855
|
+
text: p,
|
|
856
|
+
isVisible: B(t)
|
|
857
|
+
}, M;
|
|
855
858
|
}
|
|
856
859
|
if (t.nodeType === Node.ELEMENT_NODE && !it(t))
|
|
857
860
|
return null;
|
|
858
861
|
if (l !== -1 && !t.shadowRoot) {
|
|
859
|
-
const
|
|
860
|
-
if (!
|
|
862
|
+
const p = S(t), y = D(t), M = y && (y.position === "fixed" || y.position === "sticky"), C = t.offsetWidth > 0 || t.offsetHeight > 0;
|
|
863
|
+
if (!p || !M && !C && (p.bottom < -l || p.top > window.innerHeight + l || p.right < -l || p.left > window.innerWidth + l))
|
|
861
864
|
return null;
|
|
862
865
|
}
|
|
863
866
|
const c = {
|
|
@@ -869,92 +872,92 @@ const VIEWPORT_EXPANSION = -1, domTree = (e = {
|
|
|
869
872
|
// xpath: getXPathTree(node, true),
|
|
870
873
|
children: []
|
|
871
874
|
};
|
|
872
|
-
if (
|
|
873
|
-
const
|
|
874
|
-
for (const y of
|
|
875
|
-
const
|
|
876
|
-
c.attributes[y] =
|
|
875
|
+
if (O(t) || t.tagName.toLowerCase() === "iframe" || t.tagName.toLowerCase() === "body") {
|
|
876
|
+
const p = ((w = t.getAttributeNames) == null ? void 0 : w.call(t)) || [];
|
|
877
|
+
for (const y of p) {
|
|
878
|
+
const M = t.getAttribute(y);
|
|
879
|
+
c.attributes[y] = M;
|
|
877
880
|
}
|
|
878
881
|
t.tagName.toLowerCase() === "input" && (t.type === "checkbox" || t.type === "radio") && (c.attributes.checked = t.checked ? "true" : "false");
|
|
879
882
|
}
|
|
880
883
|
let a = !1;
|
|
881
884
|
if (t.nodeType === Node.ELEMENT_NODE && (c.isVisible = X(t), c.isVisible)) {
|
|
882
885
|
c.isTopElement = et(t);
|
|
883
|
-
const
|
|
884
|
-
(c.isTopElement || y) && (c.isInteractive = L(t), a = st(c, t,
|
|
886
|
+
const p = t.getAttribute("role"), y = p === "menu" || p === "menubar" || p === "listbox";
|
|
887
|
+
(c.isTopElement || y) && (c.isInteractive = L(t), a = st(c, t, r, m), c.ref = t);
|
|
885
888
|
}
|
|
886
889
|
if (t.tagName) {
|
|
887
|
-
const
|
|
888
|
-
if (
|
|
890
|
+
const p = t.tagName.toLowerCase();
|
|
891
|
+
if (p === "iframe")
|
|
889
892
|
try {
|
|
890
|
-
const y = t.contentDocument || ((
|
|
893
|
+
const y = t.contentDocument || (($ = t.contentWindow) == null ? void 0 : $.document);
|
|
891
894
|
if (y)
|
|
892
|
-
for (const
|
|
893
|
-
const
|
|
894
|
-
|
|
895
|
+
for (const M of y.childNodes) {
|
|
896
|
+
const C = Q(M, t, !1);
|
|
897
|
+
C && c.children.push(C);
|
|
895
898
|
}
|
|
896
899
|
} catch (y) {
|
|
897
900
|
console.warn("Unable to access iframe:", y);
|
|
898
901
|
}
|
|
899
|
-
else if (t.isContentEditable || t.getAttribute("contenteditable") === "true" || t.id === "tinymce" || t.classList.contains("mce-content-body") ||
|
|
902
|
+
else if (t.isContentEditable || t.getAttribute("contenteditable") === "true" || t.id === "tinymce" || t.classList.contains("mce-content-body") || p === "body" && ((A = t.getAttribute("data-id")) != null && A.startsWith("mce_")))
|
|
900
903
|
for (const y of t.childNodes) {
|
|
901
|
-
const
|
|
902
|
-
|
|
904
|
+
const M = Q(y, r, a);
|
|
905
|
+
M && c.children.push(M);
|
|
903
906
|
}
|
|
904
907
|
else {
|
|
905
908
|
if (t.shadowRoot) {
|
|
906
909
|
c.shadowRoot = !0;
|
|
907
910
|
for (const y of t.shadowRoot.childNodes) {
|
|
908
|
-
const
|
|
909
|
-
|
|
911
|
+
const M = Q(y, r, a);
|
|
912
|
+
M && c.children.push(M);
|
|
910
913
|
}
|
|
911
914
|
}
|
|
912
915
|
for (const y of t.childNodes) {
|
|
913
|
-
const
|
|
914
|
-
|
|
916
|
+
const C = Q(y, r, a || m);
|
|
917
|
+
C && c.children.push(C);
|
|
915
918
|
}
|
|
916
919
|
}
|
|
917
920
|
}
|
|
918
921
|
if (c.tagName === "a" && c.children.length === 0 && !c.attributes.href) {
|
|
919
|
-
const
|
|
920
|
-
if (!(
|
|
922
|
+
const p = S(t);
|
|
923
|
+
if (!(p && p.width > 0 && p.height > 0 || t.offsetWidth > 0 || t.offsetHeight > 0))
|
|
921
924
|
return null;
|
|
922
925
|
}
|
|
923
926
|
c.extra = b.get(t) || null;
|
|
924
|
-
const x = `${
|
|
927
|
+
const x = `${H.current++}`;
|
|
925
928
|
return _[x] = c, x;
|
|
926
929
|
}
|
|
927
930
|
const lt = Q(document.body);
|
|
928
|
-
return
|
|
931
|
+
return g.clearCache(), { rootId: lt, map: _ };
|
|
929
932
|
}, newElementsCache = /* @__PURE__ */ new WeakMap();
|
|
930
933
|
function getFlatTree(e) {
|
|
931
934
|
const n = [];
|
|
932
935
|
for (const d of e.interactiveBlacklist || [])
|
|
933
936
|
typeof d == "function" ? n.push(d()) : n.push(d);
|
|
934
|
-
const
|
|
937
|
+
const i = [];
|
|
935
938
|
for (const d of e.interactiveWhitelist || [])
|
|
936
|
-
typeof d == "function" ?
|
|
939
|
+
typeof d == "function" ? i.push(d()) : i.push(d);
|
|
937
940
|
const o = domTree({
|
|
938
941
|
doHighlightElements: !0,
|
|
939
942
|
debugMode: !0,
|
|
940
943
|
focusHighlightIndex: -1,
|
|
941
944
|
viewportExpansion: VIEWPORT_EXPANSION,
|
|
942
945
|
interactiveBlacklist: n,
|
|
943
|
-
interactiveWhitelist:
|
|
946
|
+
interactiveWhitelist: i,
|
|
944
947
|
highlightOpacity: e.highlightOpacity ?? 0,
|
|
945
948
|
highlightLabelOpacity: e.highlightLabelOpacity ?? 0.1
|
|
946
|
-
}),
|
|
949
|
+
}), f = window.location.href;
|
|
947
950
|
for (const d in o.map) {
|
|
948
|
-
const
|
|
949
|
-
if (
|
|
950
|
-
const l =
|
|
951
|
-
newElementsCache.has(l) || (newElementsCache.set(l,
|
|
951
|
+
const s = o.map[d];
|
|
952
|
+
if (s.isInteractive && s.ref) {
|
|
953
|
+
const l = s.ref;
|
|
954
|
+
newElementsCache.has(l) || (newElementsCache.set(l, f), s.isNew = !0);
|
|
952
955
|
}
|
|
953
956
|
}
|
|
954
957
|
return o;
|
|
955
958
|
}
|
|
956
959
|
function flatTreeToString(e, n) {
|
|
957
|
-
const
|
|
960
|
+
const i = [
|
|
958
961
|
"title",
|
|
959
962
|
"type",
|
|
960
963
|
"checked",
|
|
@@ -977,140 +980,140 @@ function flatTreeToString(e, n) {
|
|
|
977
980
|
"aria-haspopup",
|
|
978
981
|
"aria-controls",
|
|
979
982
|
"aria-owns"
|
|
980
|
-
], o = [...n || [], ...
|
|
981
|
-
const
|
|
982
|
-
if (!
|
|
983
|
-
if (
|
|
984
|
-
const
|
|
983
|
+
], o = [...n || [], ...i], f = (u, g) => u.length > g ? u.substring(0, g) + "..." : u, d = (u) => {
|
|
984
|
+
const g = e.map[u];
|
|
985
|
+
if (!g) return null;
|
|
986
|
+
if (g.type === "TEXT_NODE") {
|
|
987
|
+
const S = g;
|
|
985
988
|
return {
|
|
986
989
|
type: "text",
|
|
987
|
-
text:
|
|
988
|
-
isVisible:
|
|
990
|
+
text: S.text,
|
|
991
|
+
isVisible: S.isVisible,
|
|
989
992
|
parent: null,
|
|
990
993
|
children: []
|
|
991
994
|
};
|
|
992
995
|
} else {
|
|
993
|
-
const
|
|
994
|
-
if (
|
|
995
|
-
for (const z of
|
|
996
|
+
const S = g, D = [];
|
|
997
|
+
if (S.children)
|
|
998
|
+
for (const z of S.children) {
|
|
996
999
|
const _ = d(z);
|
|
997
1000
|
_ && (_.parent = null, D.push(_));
|
|
998
1001
|
}
|
|
999
1002
|
return {
|
|
1000
1003
|
type: "element",
|
|
1001
|
-
tagName:
|
|
1002
|
-
attributes:
|
|
1003
|
-
isVisible:
|
|
1004
|
-
isInteractive:
|
|
1005
|
-
isTopElement:
|
|
1006
|
-
isNew:
|
|
1007
|
-
highlightIndex:
|
|
1004
|
+
tagName: S.tagName,
|
|
1005
|
+
attributes: S.attributes ?? {},
|
|
1006
|
+
isVisible: S.isVisible ?? !1,
|
|
1007
|
+
isInteractive: S.isInteractive ?? !1,
|
|
1008
|
+
isTopElement: S.isTopElement ?? !1,
|
|
1009
|
+
isNew: S.isNew ?? !1,
|
|
1010
|
+
highlightIndex: S.highlightIndex,
|
|
1008
1011
|
parent: null,
|
|
1009
1012
|
children: D,
|
|
1010
|
-
extra:
|
|
1013
|
+
extra: S.extra ?? {}
|
|
1011
1014
|
};
|
|
1012
1015
|
}
|
|
1013
|
-
},
|
|
1014
|
-
u.parent =
|
|
1015
|
-
for (const
|
|
1016
|
-
|
|
1016
|
+
}, s = (u, g = null) => {
|
|
1017
|
+
u.parent = g;
|
|
1018
|
+
for (const S of u.children)
|
|
1019
|
+
s(S, u);
|
|
1017
1020
|
}, l = d(e.rootId);
|
|
1018
1021
|
if (!l) return "";
|
|
1019
|
-
|
|
1022
|
+
s(l);
|
|
1020
1023
|
const h = (u) => {
|
|
1021
|
-
let
|
|
1022
|
-
for (;
|
|
1023
|
-
if (
|
|
1024
|
+
let g = u.parent;
|
|
1025
|
+
for (; g; ) {
|
|
1026
|
+
if (g.type === "element" && g.highlightIndex !== void 0)
|
|
1024
1027
|
return !0;
|
|
1025
|
-
|
|
1028
|
+
g = g.parent;
|
|
1026
1029
|
}
|
|
1027
1030
|
return !1;
|
|
1028
|
-
}, T = (u,
|
|
1029
|
-
var _,
|
|
1030
|
-
let D =
|
|
1031
|
-
const z = " ".repeat(
|
|
1031
|
+
}, T = (u, g, S) => {
|
|
1032
|
+
var _, H, U, R;
|
|
1033
|
+
let D = g;
|
|
1034
|
+
const z = " ".repeat(g);
|
|
1032
1035
|
if (u.type === "element") {
|
|
1033
1036
|
if (u.highlightIndex !== void 0) {
|
|
1034
1037
|
D += 1;
|
|
1035
|
-
const
|
|
1036
|
-
let
|
|
1038
|
+
const W = getAllTextTillNextClickableElement(u);
|
|
1039
|
+
let B = "";
|
|
1037
1040
|
if (o.length > 0 && u.attributes) {
|
|
1038
1041
|
const L = {};
|
|
1039
|
-
for (const
|
|
1040
|
-
const Y = u.attributes[
|
|
1041
|
-
Y && Y.trim() !== "" && (L[
|
|
1042
|
+
for (const O of o) {
|
|
1043
|
+
const Y = u.attributes[O];
|
|
1044
|
+
Y && Y.trim() !== "" && (L[O] = Y.trim());
|
|
1042
1045
|
}
|
|
1043
|
-
const et = o.filter((
|
|
1046
|
+
const et = o.filter((O) => O in L);
|
|
1044
1047
|
if (et.length > 1) {
|
|
1045
|
-
const
|
|
1046
|
-
for (const
|
|
1047
|
-
const tt = L[
|
|
1048
|
-
tt.length > 5 && (tt in Y ?
|
|
1048
|
+
const O = /* @__PURE__ */ new Set(), Y = {};
|
|
1049
|
+
for (const J of et) {
|
|
1050
|
+
const tt = L[J];
|
|
1051
|
+
tt.length > 5 && (tt in Y ? O.add(J) : Y[tt] = J);
|
|
1049
1052
|
}
|
|
1050
|
-
for (const
|
|
1051
|
-
delete L[
|
|
1053
|
+
for (const J of O)
|
|
1054
|
+
delete L[J];
|
|
1052
1055
|
}
|
|
1053
1056
|
L.role === u.tagName && delete L.role;
|
|
1054
1057
|
const ot = ["aria-label", "placeholder", "title"];
|
|
1055
|
-
for (const
|
|
1056
|
-
L[
|
|
1057
|
-
Object.keys(L).length > 0 && (
|
|
1058
|
+
for (const O of ot)
|
|
1059
|
+
L[O] && L[O].toLowerCase().trim() === W.toLowerCase().trim() && delete L[O];
|
|
1060
|
+
Object.keys(L).length > 0 && (B = Object.entries(L).map(([O, Y]) => `${O}=${f(Y, 20)}`).join(" "));
|
|
1058
1061
|
}
|
|
1059
1062
|
const it = u.isNew ? `*[${u.highlightIndex}]` : `[${u.highlightIndex}]`;
|
|
1060
1063
|
let X = `${z}${it}<${u.tagName ?? ""}`;
|
|
1061
|
-
if (
|
|
1064
|
+
if (B && (X += ` ${B}`), u.extra && u.extra.scrollable) {
|
|
1062
1065
|
let L = "";
|
|
1063
|
-
(_ = u.extra.scrollData) != null && _.left && (L += `left=${u.extra.scrollData.left}, `), (
|
|
1066
|
+
(_ = u.extra.scrollData) != null && _.left && (L += `left=${u.extra.scrollData.left}, `), (H = u.extra.scrollData) != null && H.top && (L += `top=${u.extra.scrollData.top}, `), (U = u.extra.scrollData) != null && U.right && (L += `right=${u.extra.scrollData.right}, `), (R = u.extra.scrollData) != null && R.bottom && (L += `bottom=${u.extra.scrollData.bottom}`), X += ` data-scrollable="${L}"`;
|
|
1064
1067
|
}
|
|
1065
|
-
if (
|
|
1066
|
-
const L =
|
|
1067
|
-
|
|
1068
|
-
} else
|
|
1069
|
-
X += " />",
|
|
1068
|
+
if (W) {
|
|
1069
|
+
const L = W.trim();
|
|
1070
|
+
B || (X += " "), X += `>${L}`;
|
|
1071
|
+
} else B || (X += " ");
|
|
1072
|
+
X += " />", S.push(X);
|
|
1070
1073
|
}
|
|
1071
|
-
for (const
|
|
1072
|
-
T(
|
|
1074
|
+
for (const W of u.children)
|
|
1075
|
+
T(W, D, S);
|
|
1073
1076
|
} else if (u.type === "text") {
|
|
1074
1077
|
if (h(u))
|
|
1075
1078
|
return;
|
|
1076
|
-
u.parent && u.parent.type === "element" && u.parent.isVisible && u.parent.isTopElement &&
|
|
1079
|
+
u.parent && u.parent.type === "element" && u.parent.isVisible && u.parent.isTopElement && S.push(`${z}${u.text ?? ""}`);
|
|
1077
1080
|
}
|
|
1078
1081
|
}, b = [];
|
|
1079
1082
|
return T(l, 0, b), b.join(`
|
|
1080
1083
|
`);
|
|
1081
1084
|
}
|
|
1082
1085
|
const getAllTextTillNextClickableElement = (e, n = -1) => {
|
|
1083
|
-
const
|
|
1084
|
-
if (!(n !== -1 && d > n) && !(
|
|
1085
|
-
if (
|
|
1086
|
-
|
|
1087
|
-
else if (
|
|
1088
|
-
for (const
|
|
1089
|
-
o(
|
|
1086
|
+
const i = [], o = (f, d) => {
|
|
1087
|
+
if (!(n !== -1 && d > n) && !(f.type === "element" && f !== e && f.highlightIndex !== void 0)) {
|
|
1088
|
+
if (f.type === "text" && f.text)
|
|
1089
|
+
i.push(f.text);
|
|
1090
|
+
else if (f.type === "element")
|
|
1091
|
+
for (const s of f.children)
|
|
1092
|
+
o(s, d + 1);
|
|
1090
1093
|
}
|
|
1091
1094
|
};
|
|
1092
|
-
return o(e, 0),
|
|
1095
|
+
return o(e, 0), i.join(`
|
|
1093
1096
|
`).trim();
|
|
1094
1097
|
};
|
|
1095
1098
|
function getSelectorMap(e) {
|
|
1096
|
-
const n = /* @__PURE__ */ new Map(),
|
|
1097
|
-
for (const o of
|
|
1098
|
-
const
|
|
1099
|
-
|
|
1099
|
+
const n = /* @__PURE__ */ new Map(), i = Object.keys(e.map);
|
|
1100
|
+
for (const o of i) {
|
|
1101
|
+
const f = e.map[o];
|
|
1102
|
+
f.isInteractive && typeof f.highlightIndex == "number" && n.set(f.highlightIndex, f);
|
|
1100
1103
|
}
|
|
1101
1104
|
return n;
|
|
1102
1105
|
}
|
|
1103
1106
|
function getElementTextMap(e) {
|
|
1104
1107
|
const n = e.split(`
|
|
1105
|
-
`).map((o) => o.trim()).filter((o) => o.length > 0),
|
|
1108
|
+
`).map((o) => o.trim()).filter((o) => o.length > 0), i = /* @__PURE__ */ new Map();
|
|
1106
1109
|
for (const o of n) {
|
|
1107
1110
|
const d = /^\[(\d+)\]<[^>]+>([^<]*)/.exec(o);
|
|
1108
1111
|
if (d) {
|
|
1109
|
-
const
|
|
1110
|
-
|
|
1112
|
+
const s = parseInt(d[1], 10);
|
|
1113
|
+
i.set(s, o);
|
|
1111
1114
|
}
|
|
1112
1115
|
}
|
|
1113
|
-
return
|
|
1116
|
+
return i;
|
|
1114
1117
|
}
|
|
1115
1118
|
function cleanUpHighlights() {
|
|
1116
1119
|
const e = window._highlightCleanupFunctions || [];
|
|
@@ -1139,27 +1142,27 @@ else {
|
|
|
1139
1142
|
}, 500);
|
|
1140
1143
|
}
|
|
1141
1144
|
function getPageInfo() {
|
|
1142
|
-
const e = window.innerWidth, n = window.innerHeight,
|
|
1145
|
+
const e = window.innerWidth, n = window.innerHeight, i = Math.max(document.documentElement.scrollWidth, document.body.scrollWidth || 0), o = Math.max(
|
|
1143
1146
|
document.documentElement.scrollHeight,
|
|
1144
1147
|
document.body.scrollHeight || 0
|
|
1145
|
-
),
|
|
1148
|
+
), f = window.scrollX || window.pageXOffset || document.documentElement.scrollLeft || 0, d = window.scrollY || window.pageYOffset || document.documentElement.scrollTop || 0, s = Math.max(0, o - (window.innerHeight + d)), l = Math.max(0, i - (window.innerWidth + f));
|
|
1146
1149
|
return {
|
|
1147
1150
|
// Current viewport dimensions
|
|
1148
1151
|
viewport_width: e,
|
|
1149
1152
|
viewport_height: n,
|
|
1150
1153
|
// Total page dimensions
|
|
1151
|
-
page_width:
|
|
1154
|
+
page_width: i,
|
|
1152
1155
|
page_height: o,
|
|
1153
1156
|
// Current scroll position
|
|
1154
|
-
scroll_x:
|
|
1157
|
+
scroll_x: f,
|
|
1155
1158
|
scroll_y: d,
|
|
1156
1159
|
pixels_above: d,
|
|
1157
|
-
pixels_below:
|
|
1160
|
+
pixels_below: s,
|
|
1158
1161
|
pages_above: n > 0 ? d / n : 0,
|
|
1159
|
-
pages_below: n > 0 ?
|
|
1162
|
+
pages_below: n > 0 ? s / n : 0,
|
|
1160
1163
|
total_pages: n > 0 ? o / n : 0,
|
|
1161
1164
|
current_page_position: d / Math.max(1, o - n),
|
|
1162
|
-
pixels_left:
|
|
1165
|
+
pixels_left: f,
|
|
1163
1166
|
pixels_right: l
|
|
1164
1167
|
};
|
|
1165
1168
|
}
|
|
@@ -1167,8 +1170,8 @@ function patchReact(e) {
|
|
|
1167
1170
|
const n = document.querySelectorAll(
|
|
1168
1171
|
'[data-reactroot], [data-reactid], [data-react-checksum], #root, #app, [id^="root-"], [id^="app-"], #adex-wrapper, #adex-root'
|
|
1169
1172
|
);
|
|
1170
|
-
for (const
|
|
1171
|
-
|
|
1173
|
+
for (const i of n)
|
|
1174
|
+
i.setAttribute("data-page-agent-not-interactive", "true");
|
|
1172
1175
|
}
|
|
1173
1176
|
class PageController extends EventTarget {
|
|
1174
1177
|
constructor(e = {}) {
|
|
@@ -1201,15 +1204,15 @@ class PageController extends EventTarget {
|
|
|
1201
1204
|
* Automatically calls updateTree() to refresh the DOM state.
|
|
1202
1205
|
*/
|
|
1203
1206
|
async getBrowserState() {
|
|
1204
|
-
const e = window.location.href, n = document.title,
|
|
1207
|
+
const e = window.location.href, n = document.title, i = getPageInfo(), o = this.config.viewportExpansion ?? VIEWPORT_EXPANSION;
|
|
1205
1208
|
await this.updateTree();
|
|
1206
|
-
const
|
|
1207
|
-
${
|
|
1209
|
+
const f = this.simplifiedHTML, d = `Current Page: [${n}](${e})`, s = `Page info: ${i.viewport_width}x${i.viewport_height}px viewport, ${i.page_width}x${i.page_height}px total page size, ${i.pages_above.toFixed(1)} pages above, ${i.pages_below.toFixed(1)} pages below, ${i.total_pages.toFixed(1)} total pages, at ${(i.current_page_position * 100).toFixed(0)}% of page`, l = o === -1 ? "Interactive elements from top layer of the current page (full page):" : "Interactive elements from top layer of the current page inside the viewport:", T = i.pixels_above > 4 && o !== -1 ? `... ${i.pixels_above} pixels above (${i.pages_above.toFixed(1)} pages) - scroll to see more ...` : "[Start of page]", b = `${d}
|
|
1210
|
+
${s}
|
|
1208
1211
|
|
|
1209
1212
|
${l}
|
|
1210
1213
|
|
|
1211
|
-
${T}`,
|
|
1212
|
-
return { url: e, title: n, header: b, content:
|
|
1214
|
+
${T}`, g = i.pixels_below > 4 && o !== -1 ? `... ${i.pixels_below} pixels below (${i.pages_below.toFixed(1)} pages) - scroll to see more ...` : "[End of page]";
|
|
1215
|
+
return { url: e, title: n, header: b, content: f, footer: g };
|
|
1213
1216
|
}
|
|
1214
1217
|
// ======= DOM Tree Operations =======
|
|
1215
1218
|
/**
|
|
@@ -1249,13 +1252,13 @@ ${T}`, f = s.pixels_below > 4 && o !== -1 ? `... ${s.pixels_below} pixels below
|
|
|
1249
1252
|
async clickElement(e) {
|
|
1250
1253
|
try {
|
|
1251
1254
|
this.assertIndexed();
|
|
1252
|
-
const n = getElementByIndex(this.selectorMap, e),
|
|
1255
|
+
const n = getElementByIndex(this.selectorMap, e), i = this.elementTextMap.get(e);
|
|
1253
1256
|
return await clickElement(n), n instanceof HTMLAnchorElement && n.target === "_blank" ? {
|
|
1254
1257
|
success: !0,
|
|
1255
|
-
message: `✅ Clicked element (${
|
|
1258
|
+
message: `✅ Clicked element (${i ?? e}). ⚠️ Link opens in a new tab. You are not capable of reading new tabs.`
|
|
1256
1259
|
} : {
|
|
1257
1260
|
success: !0,
|
|
1258
|
-
message: `✅ Clicked element (${
|
|
1261
|
+
message: `✅ Clicked element (${i ?? e}).`
|
|
1259
1262
|
};
|
|
1260
1263
|
} catch (n) {
|
|
1261
1264
|
return {
|
|
@@ -1270,15 +1273,15 @@ ${T}`, f = s.pixels_below > 4 && o !== -1 ? `... ${s.pixels_below} pixels below
|
|
|
1270
1273
|
async inputText(e, n) {
|
|
1271
1274
|
try {
|
|
1272
1275
|
this.assertIndexed();
|
|
1273
|
-
const
|
|
1274
|
-
return await inputTextElement(
|
|
1276
|
+
const i = getElementByIndex(this.selectorMap, e), o = this.elementTextMap.get(e);
|
|
1277
|
+
return await inputTextElement(i, n), {
|
|
1275
1278
|
success: !0,
|
|
1276
1279
|
message: `✅ Input text (${n}) into element (${o ?? e}).`
|
|
1277
1280
|
};
|
|
1278
|
-
} catch (
|
|
1281
|
+
} catch (i) {
|
|
1279
1282
|
return {
|
|
1280
1283
|
success: !1,
|
|
1281
|
-
message: `❌ Failed to input text: ${
|
|
1284
|
+
message: `❌ Failed to input text: ${i}`
|
|
1282
1285
|
};
|
|
1283
1286
|
}
|
|
1284
1287
|
}
|
|
@@ -1288,15 +1291,15 @@ ${T}`, f = s.pixels_below > 4 && o !== -1 ? `... ${s.pixels_below} pixels below
|
|
|
1288
1291
|
async selectOption(e, n) {
|
|
1289
1292
|
try {
|
|
1290
1293
|
this.assertIndexed();
|
|
1291
|
-
const
|
|
1292
|
-
return await selectOptionElement(
|
|
1294
|
+
const i = getElementByIndex(this.selectorMap, e), o = this.elementTextMap.get(e);
|
|
1295
|
+
return await selectOptionElement(i, n), {
|
|
1293
1296
|
success: !0,
|
|
1294
1297
|
message: `✅ Selected option (${n}) in element (${o ?? e}).`
|
|
1295
1298
|
};
|
|
1296
|
-
} catch (
|
|
1299
|
+
} catch (i) {
|
|
1297
1300
|
return {
|
|
1298
1301
|
success: !1,
|
|
1299
|
-
message: `❌ Failed to select option: ${
|
|
1302
|
+
message: `❌ Failed to select option: ${i}`
|
|
1300
1303
|
};
|
|
1301
1304
|
}
|
|
1302
1305
|
}
|
|
@@ -1305,12 +1308,12 @@ ${T}`, f = s.pixels_below > 4 && o !== -1 ? `... ${s.pixels_below} pixels below
|
|
|
1305
1308
|
*/
|
|
1306
1309
|
async scroll(e) {
|
|
1307
1310
|
try {
|
|
1308
|
-
const { down: n, numPages:
|
|
1311
|
+
const { down: n, numPages: i, pixels: o, index: f } = e;
|
|
1309
1312
|
this.assertIndexed();
|
|
1310
|
-
const d = o ??
|
|
1313
|
+
const d = o ?? i * (n ? 1 : -1) * window.innerHeight, s = f !== void 0 ? getElementByIndex(this.selectorMap, f) : null;
|
|
1311
1314
|
return {
|
|
1312
1315
|
success: !0,
|
|
1313
|
-
message: await scrollVertically(n, d,
|
|
1316
|
+
message: await scrollVertically(n, d, s)
|
|
1314
1317
|
};
|
|
1315
1318
|
} catch (n) {
|
|
1316
1319
|
return {
|
|
@@ -1324,12 +1327,12 @@ ${T}`, f = s.pixels_below > 4 && o !== -1 ? `... ${s.pixels_below} pixels below
|
|
|
1324
1327
|
*/
|
|
1325
1328
|
async scrollHorizontally(e) {
|
|
1326
1329
|
try {
|
|
1327
|
-
const { right: n, pixels:
|
|
1330
|
+
const { right: n, pixels: i, index: o } = e;
|
|
1328
1331
|
this.assertIndexed();
|
|
1329
|
-
const
|
|
1332
|
+
const f = i * (n ? 1 : -1), d = o !== void 0 ? getElementByIndex(this.selectorMap, o) : null;
|
|
1330
1333
|
return {
|
|
1331
1334
|
success: !0,
|
|
1332
|
-
message: await scrollHorizontally(n,
|
|
1335
|
+
message: await scrollHorizontally(n, f, d)
|
|
1333
1336
|
};
|
|
1334
1337
|
} catch (n) {
|
|
1335
1338
|
return {
|
|
@@ -1355,6 +1358,209 @@ ${T}`, f = s.pixels_below > 4 && o !== -1 ? `... ${s.pixels_below} pixels below
|
|
|
1355
1358
|
};
|
|
1356
1359
|
}
|
|
1357
1360
|
}
|
|
1361
|
+
// ======= Workflow Element Finding =======
|
|
1362
|
+
/**
|
|
1363
|
+
* Find an interactive element index by visible text (exact match).
|
|
1364
|
+
* Scans the elementTextMap for a match.
|
|
1365
|
+
*/
|
|
1366
|
+
findElementByText(e, n = !0) {
|
|
1367
|
+
const i = e.trim().toLowerCase();
|
|
1368
|
+
for (const [o, f] of this.elementTextMap.entries()) {
|
|
1369
|
+
const d = f.trim().toLowerCase();
|
|
1370
|
+
if (n) {
|
|
1371
|
+
if (d === i || d.includes(i))
|
|
1372
|
+
return o;
|
|
1373
|
+
} else if (d.includes(i) || i.includes(d))
|
|
1374
|
+
return o;
|
|
1375
|
+
}
|
|
1376
|
+
return null;
|
|
1377
|
+
}
|
|
1378
|
+
/**
|
|
1379
|
+
* Find an interactive element index by CSS selector.
|
|
1380
|
+
* Queries the DOM, then reverse-looks up in selectorMap.
|
|
1381
|
+
*/
|
|
1382
|
+
findElementBySelector(e) {
|
|
1383
|
+
try {
|
|
1384
|
+
const n = document.querySelector(e);
|
|
1385
|
+
if (!n) return null;
|
|
1386
|
+
for (const [o, f] of this.selectorMap.entries())
|
|
1387
|
+
if (f.ref === n) return o;
|
|
1388
|
+
let i = n.parentElement;
|
|
1389
|
+
for (; i && i !== document.body; ) {
|
|
1390
|
+
for (const [o, f] of this.selectorMap.entries())
|
|
1391
|
+
if (f.ref === i) return o;
|
|
1392
|
+
i = i.parentElement;
|
|
1393
|
+
}
|
|
1394
|
+
return null;
|
|
1395
|
+
} catch {
|
|
1396
|
+
return null;
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
/**
|
|
1400
|
+
* Find an interactive element index by XPath.
|
|
1401
|
+
* Evaluates the XPath, then reverse-looks up in selectorMap.
|
|
1402
|
+
*/
|
|
1403
|
+
findElementByXPath(e) {
|
|
1404
|
+
try {
|
|
1405
|
+
const i = document.evaluate(
|
|
1406
|
+
e,
|
|
1407
|
+
document,
|
|
1408
|
+
null,
|
|
1409
|
+
XPathResult.FIRST_ORDERED_NODE_TYPE,
|
|
1410
|
+
null
|
|
1411
|
+
).singleNodeValue;
|
|
1412
|
+
if (!i) return null;
|
|
1413
|
+
for (const [o, f] of this.selectorMap.entries())
|
|
1414
|
+
if (f.ref === i) return o;
|
|
1415
|
+
return null;
|
|
1416
|
+
} catch {
|
|
1417
|
+
return null;
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
/**
|
|
1421
|
+
* Find an interactive element index by aria-label attribute.
|
|
1422
|
+
*/
|
|
1423
|
+
findElementByAriaLabel(e) {
|
|
1424
|
+
return this.findElementBySelector(`[aria-label="${CSS.escape(e)}"]`);
|
|
1425
|
+
}
|
|
1426
|
+
/**
|
|
1427
|
+
* Find an interactive element index by placeholder text.
|
|
1428
|
+
*/
|
|
1429
|
+
findElementByPlaceholder(e) {
|
|
1430
|
+
return this.findElementBySelector(`[placeholder="${CSS.escape(e)}"]`);
|
|
1431
|
+
}
|
|
1432
|
+
/**
|
|
1433
|
+
* Multi-strategy element finder. Tries strategies in priority order.
|
|
1434
|
+
* Returns the index of the first match, or null if nothing found.
|
|
1435
|
+
*/
|
|
1436
|
+
findElementByStrategies(e) {
|
|
1437
|
+
const n = [...e].sort((i, o) => i.priority - o.priority);
|
|
1438
|
+
for (const i of n) {
|
|
1439
|
+
let o = null;
|
|
1440
|
+
switch (i.type) {
|
|
1441
|
+
case "text_exact":
|
|
1442
|
+
o = this.findElementByText(i.value, !0);
|
|
1443
|
+
break;
|
|
1444
|
+
case "text_contains":
|
|
1445
|
+
o = this.findElementByText(i.value, !1);
|
|
1446
|
+
break;
|
|
1447
|
+
case "aria_label":
|
|
1448
|
+
o = this.findElementByAriaLabel(i.value);
|
|
1449
|
+
break;
|
|
1450
|
+
case "placeholder":
|
|
1451
|
+
o = this.findElementByPlaceholder(i.value);
|
|
1452
|
+
break;
|
|
1453
|
+
case "css":
|
|
1454
|
+
o = this.findElementBySelector(i.value);
|
|
1455
|
+
break;
|
|
1456
|
+
case "xpath":
|
|
1457
|
+
o = this.findElementByXPath(i.value);
|
|
1458
|
+
break;
|
|
1459
|
+
}
|
|
1460
|
+
if (o !== null) return o;
|
|
1461
|
+
}
|
|
1462
|
+
return null;
|
|
1463
|
+
}
|
|
1464
|
+
// ======= New Workflow Actions =======
|
|
1465
|
+
/**
|
|
1466
|
+
* Press a key on an element (or the active element if no index provided).
|
|
1467
|
+
*/
|
|
1468
|
+
async pressKey(e, n) {
|
|
1469
|
+
try {
|
|
1470
|
+
let i;
|
|
1471
|
+
return n !== void 0 ? (this.assertIndexed(), i = getElementByIndex(this.selectorMap, n)) : i = document.activeElement || document.body, await createSyntheticInputEvent(i, e), {
|
|
1472
|
+
success: !0,
|
|
1473
|
+
message: `✅ Pressed key "${e}" on element.`
|
|
1474
|
+
};
|
|
1475
|
+
} catch (i) {
|
|
1476
|
+
return {
|
|
1477
|
+
success: !1,
|
|
1478
|
+
message: `❌ Failed to press key: ${i}`
|
|
1479
|
+
};
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
/**
|
|
1483
|
+
* Navigate to a URL. Restricts to same-origin http(s) URLs for security.
|
|
1484
|
+
*/
|
|
1485
|
+
async navigateToUrl(e) {
|
|
1486
|
+
try {
|
|
1487
|
+
const n = new URL(e, window.location.origin);
|
|
1488
|
+
return n.protocol !== "http:" && n.protocol !== "https:" ? {
|
|
1489
|
+
success: !1,
|
|
1490
|
+
message: `❌ Blocked navigation to disallowed scheme: ${n.protocol}`
|
|
1491
|
+
} : n.origin !== window.location.origin ? {
|
|
1492
|
+
success: !1,
|
|
1493
|
+
message: `❌ Blocked cross-origin navigation to ${n.origin}`
|
|
1494
|
+
} : (window.location.href = n.href, {
|
|
1495
|
+
success: !0,
|
|
1496
|
+
message: `✅ Navigating to ${n.href}`
|
|
1497
|
+
});
|
|
1498
|
+
} catch (n) {
|
|
1499
|
+
return {
|
|
1500
|
+
success: !1,
|
|
1501
|
+
message: `❌ Failed to navigate: ${n}`
|
|
1502
|
+
};
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
/**
|
|
1506
|
+
* Go back in browser history.
|
|
1507
|
+
*/
|
|
1508
|
+
async goBack() {
|
|
1509
|
+
try {
|
|
1510
|
+
return window.history.back(), {
|
|
1511
|
+
success: !0,
|
|
1512
|
+
message: "✅ Navigated back."
|
|
1513
|
+
};
|
|
1514
|
+
} catch (e) {
|
|
1515
|
+
return {
|
|
1516
|
+
success: !1,
|
|
1517
|
+
message: `❌ Failed to go back: ${e}`
|
|
1518
|
+
};
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
/**
|
|
1522
|
+
* Go forward in browser history.
|
|
1523
|
+
*/
|
|
1524
|
+
async goForward() {
|
|
1525
|
+
try {
|
|
1526
|
+
return window.history.forward(), {
|
|
1527
|
+
success: !0,
|
|
1528
|
+
message: "✅ Navigated forward."
|
|
1529
|
+
};
|
|
1530
|
+
} catch (e) {
|
|
1531
|
+
return {
|
|
1532
|
+
success: !1,
|
|
1533
|
+
message: `❌ Failed to go forward: ${e}`
|
|
1534
|
+
};
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
/**
|
|
1538
|
+
* Wait until an element matching the given strategies appears in the DOM,
|
|
1539
|
+
* or until the timeout is reached. Refreshes the DOM tree on each poll.
|
|
1540
|
+
*/
|
|
1541
|
+
async waitForElement(e, n = 3e3, i = 300) {
|
|
1542
|
+
const o = Date.now();
|
|
1543
|
+
for (; Date.now() - o < n; ) {
|
|
1544
|
+
await this.updateTree();
|
|
1545
|
+
const f = this.findElementByStrategies(e);
|
|
1546
|
+
if (f !== null) return f;
|
|
1547
|
+
await new Promise((d) => setTimeout(d, i));
|
|
1548
|
+
}
|
|
1549
|
+
return null;
|
|
1550
|
+
}
|
|
1551
|
+
// ======= Accessors for WorkflowExecutor =======
|
|
1552
|
+
/**
|
|
1553
|
+
* Get the current selectorMap (for external use like WorkflowExecutor).
|
|
1554
|
+
*/
|
|
1555
|
+
getSelectorMap() {
|
|
1556
|
+
return this.selectorMap;
|
|
1557
|
+
}
|
|
1558
|
+
/**
|
|
1559
|
+
* Get the current elementTextMap (for external use like WorkflowExecutor).
|
|
1560
|
+
*/
|
|
1561
|
+
getElementTextMap() {
|
|
1562
|
+
return this.elementTextMap;
|
|
1563
|
+
}
|
|
1358
1564
|
// ======= Mask Operations =======
|
|
1359
1565
|
/**
|
|
1360
1566
|
* Show the visual mask overlay.
|