@page-agent/page-controller 1.7.0 → 1.8.0-beta.0
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/lib/PageController.d.ts +8 -9
- package/dist/lib/{SimulatorMask-CU7szDjy.js → SimulatorMask-BfJiQVCo.js} +76 -98
- package/dist/lib/SimulatorMask-BfJiQVCo.js.map +1 -0
- package/dist/lib/page-controller.js +125 -111
- package/dist/lib/page-controller.js.map +1 -1
- package/package.json +5 -5
- package/dist/lib/SimulatorMask-CU7szDjy.js.map +0 -1
|
@@ -48,6 +48,11 @@ declare interface DomConfig {
|
|
|
48
48
|
includeAttributes?: string[];
|
|
49
49
|
highlightOpacity?: number;
|
|
50
50
|
highlightLabelOpacity?: number;
|
|
51
|
+
/**
|
|
52
|
+
* Preserve semantic landmark tags in dehydrated output even if not interactive
|
|
53
|
+
* @note maybe confusing for LLM combining with page scrolling, use with caution
|
|
54
|
+
**/
|
|
55
|
+
keepSemanticTags?: boolean;
|
|
51
56
|
}
|
|
52
57
|
|
|
53
58
|
declare type DomNode = TextDomNode | ElementDomNode | InteractiveElementDomNode;
|
|
@@ -95,7 +100,7 @@ declare interface FlatDomTree {
|
|
|
95
100
|
*
|
|
96
101
|
* @todo 数据脱敏过滤器
|
|
97
102
|
*/
|
|
98
|
-
declare function flatTreeToString(flatTree: FlatDomTree, includeAttributes?: string[]): string;
|
|
103
|
+
declare function flatTreeToString(flatTree: FlatDomTree, includeAttributes?: string[], keepSemanticTags?: boolean): string;
|
|
99
104
|
|
|
100
105
|
declare const getAllTextTillNextClickableElement: (node: TreeNode, maxDepth?: number) => string;
|
|
101
106
|
|
|
@@ -256,20 +261,14 @@ export declare interface PageControllerConfig extends dom.DomConfig {
|
|
|
256
261
|
|
|
257
262
|
declare function resolveViewportExpansion(viewportExpansion?: number): number;
|
|
258
263
|
|
|
259
|
-
|
|
260
|
-
* @private Internal method, subject to change at any time.
|
|
261
|
-
*/
|
|
262
|
-
export declare function scrollHorizontally(right: boolean, scroll_amount: number, element?: HTMLElement | null): Promise<string>;
|
|
264
|
+
export declare function scrollHorizontally(scroll_amount: number, element?: HTMLElement | null): Promise<string>;
|
|
263
265
|
|
|
264
266
|
/**
|
|
265
267
|
* @private Internal method, subject to change at any time.
|
|
266
268
|
*/
|
|
267
269
|
export declare function scrollIntoViewIfNeeded(element: Element): Promise<void>;
|
|
268
270
|
|
|
269
|
-
|
|
270
|
-
* @private Internal method, subject to change at any time.
|
|
271
|
-
*/
|
|
272
|
-
export declare function scrollVertically(down: boolean, scroll_amount: number, element?: HTMLElement | null): Promise<string>;
|
|
271
|
+
export declare function scrollVertically(scroll_amount: number, element?: HTMLElement | null): Promise<string>;
|
|
273
272
|
|
|
274
273
|
/**
|
|
275
274
|
* @todo browser-use version is very complex and supports menu tags, need to follow up
|
|
@@ -92,19 +92,6 @@
|
|
|
92
92
|
console.error("vite-plugin-css-injected-by-js", e);
|
|
93
93
|
}
|
|
94
94
|
})();
|
|
95
|
-
var __defProp = Object.defineProperty;
|
|
96
|
-
var __typeError = (msg) => {
|
|
97
|
-
throw TypeError(msg);
|
|
98
|
-
};
|
|
99
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
100
|
-
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
101
|
-
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
102
|
-
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
103
|
-
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
104
|
-
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
105
|
-
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
106
|
-
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
107
|
-
var _cursor, _currentCursorX, _currentCursorY, _targetCursorX, _targetCursorY, _SimulatorMask_instances, createCursor_fn, moveCursorToTarget_fn;
|
|
108
95
|
import { Motion } from "ai-motion";
|
|
109
96
|
function hasDarkModeClass() {
|
|
110
97
|
const DEFAULT_DARK_MODE_CLASSES = ["dark", "dark-mode", "theme-dark", "night", "night-mode"];
|
|
@@ -121,7 +108,6 @@ function hasDarkModeClass() {
|
|
|
121
108
|
}
|
|
122
109
|
return false;
|
|
123
110
|
}
|
|
124
|
-
__name(hasDarkModeClass, "hasDarkModeClass");
|
|
125
111
|
function parseRgbColor(colorString) {
|
|
126
112
|
const rgbMatch = /rgba?\((\d+),\s*(\d+),\s*(\d+)/.exec(colorString);
|
|
127
113
|
if (!rgbMatch) {
|
|
@@ -133,7 +119,6 @@ function parseRgbColor(colorString) {
|
|
|
133
119
|
b: parseInt(rgbMatch[3])
|
|
134
120
|
};
|
|
135
121
|
}
|
|
136
|
-
__name(parseRgbColor, "parseRgbColor");
|
|
137
122
|
function isColorDark(colorString, threshold = 128) {
|
|
138
123
|
if (!colorString || colorString === "transparent" || colorString.startsWith("rgba(0, 0, 0, 0)")) {
|
|
139
124
|
return false;
|
|
@@ -145,7 +130,6 @@ function isColorDark(colorString, threshold = 128) {
|
|
|
145
130
|
const luminance = 0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b;
|
|
146
131
|
return luminance < threshold;
|
|
147
132
|
}
|
|
148
|
-
__name(isColorDark, "isColorDark");
|
|
149
133
|
function isBackgroundDark() {
|
|
150
134
|
const htmlStyle = window.getComputedStyle(document.documentElement);
|
|
151
135
|
const bodyStyle = window.getComputedStyle(document.body || document.documentElement);
|
|
@@ -158,7 +142,6 @@ function isBackgroundDark() {
|
|
|
158
142
|
}
|
|
159
143
|
return false;
|
|
160
144
|
}
|
|
161
|
-
__name(isBackgroundDark, "isBackgroundDark");
|
|
162
145
|
function isPageDark() {
|
|
163
146
|
try {
|
|
164
147
|
if (hasDarkModeClass()) {
|
|
@@ -173,7 +156,6 @@ function isPageDark() {
|
|
|
173
156
|
return false;
|
|
174
157
|
}
|
|
175
158
|
}
|
|
176
|
-
__name(isPageDark, "isPageDark");
|
|
177
159
|
const wrapper = "_wrapper_1ooyb_1";
|
|
178
160
|
const visible = "_visible_1ooyb_11";
|
|
179
161
|
const styles = {
|
|
@@ -192,18 +174,18 @@ const cursorStyles = {
|
|
|
192
174
|
cursorRipple,
|
|
193
175
|
clicking
|
|
194
176
|
};
|
|
195
|
-
|
|
177
|
+
class SimulatorMask extends EventTarget {
|
|
178
|
+
shown = false;
|
|
179
|
+
wrapper = document.createElement("div");
|
|
180
|
+
motion = null;
|
|
181
|
+
#disposed = false;
|
|
182
|
+
#cursor = document.createElement("div");
|
|
183
|
+
#currentCursorX = 0;
|
|
184
|
+
#currentCursorY = 0;
|
|
185
|
+
#targetCursorX = 0;
|
|
186
|
+
#targetCursorY = 0;
|
|
196
187
|
constructor() {
|
|
197
188
|
super();
|
|
198
|
-
__privateAdd(this, _SimulatorMask_instances);
|
|
199
|
-
__publicField(this, "shown", false);
|
|
200
|
-
__publicField(this, "wrapper", document.createElement("div"));
|
|
201
|
-
__publicField(this, "motion", null);
|
|
202
|
-
__privateAdd(this, _cursor, document.createElement("div"));
|
|
203
|
-
__privateAdd(this, _currentCursorX, 0);
|
|
204
|
-
__privateAdd(this, _currentCursorY, 0);
|
|
205
|
-
__privateAdd(this, _targetCursorX, 0);
|
|
206
|
-
__privateAdd(this, _targetCursorY, 0);
|
|
207
189
|
this.wrapper.id = "page-agent-runtime_simulator-mask";
|
|
208
190
|
this.wrapper.className = styles.wrapper;
|
|
209
191
|
this.wrapper.setAttribute("data-browser-use-ignore", "true");
|
|
@@ -247,22 +229,22 @@ const _SimulatorMask = class _SimulatorMask extends EventTarget {
|
|
|
247
229
|
e.stopPropagation();
|
|
248
230
|
e.preventDefault();
|
|
249
231
|
});
|
|
250
|
-
|
|
232
|
+
this.#createCursor();
|
|
251
233
|
document.body.appendChild(this.wrapper);
|
|
252
|
-
|
|
253
|
-
const movePointerToListener =
|
|
234
|
+
this.#moveCursorToTarget();
|
|
235
|
+
const movePointerToListener = (event) => {
|
|
254
236
|
const { x, y } = event.detail;
|
|
255
237
|
this.setCursorPosition(x, y);
|
|
256
|
-
}
|
|
257
|
-
const clickPointerListener =
|
|
238
|
+
};
|
|
239
|
+
const clickPointerListener = () => {
|
|
258
240
|
this.triggerClickAnimation();
|
|
259
|
-
}
|
|
260
|
-
const enablePassThroughListener =
|
|
241
|
+
};
|
|
242
|
+
const enablePassThroughListener = () => {
|
|
261
243
|
this.wrapper.style.pointerEvents = "none";
|
|
262
|
-
}
|
|
263
|
-
const disablePassThroughListener =
|
|
244
|
+
};
|
|
245
|
+
const disablePassThroughListener = () => {
|
|
264
246
|
this.wrapper.style.pointerEvents = "auto";
|
|
265
|
-
}
|
|
247
|
+
};
|
|
266
248
|
window.addEventListener("PageAgent::MovePointerTo", movePointerToListener);
|
|
267
249
|
window.addEventListener("PageAgent::ClickPointer", clickPointerListener);
|
|
268
250
|
window.addEventListener("PageAgent::EnablePassThrough", enablePassThroughListener);
|
|
@@ -274,90 +256,86 @@ const _SimulatorMask = class _SimulatorMask extends EventTarget {
|
|
|
274
256
|
window.removeEventListener("PageAgent::DisablePassThrough", disablePassThroughListener);
|
|
275
257
|
});
|
|
276
258
|
}
|
|
259
|
+
#createCursor() {
|
|
260
|
+
this.#cursor.className = cursorStyles.cursor;
|
|
261
|
+
const rippleContainer = document.createElement("div");
|
|
262
|
+
rippleContainer.className = cursorStyles.cursorRipple;
|
|
263
|
+
this.#cursor.appendChild(rippleContainer);
|
|
264
|
+
const fillingLayer = document.createElement("div");
|
|
265
|
+
fillingLayer.className = cursorStyles.cursorFilling;
|
|
266
|
+
this.#cursor.appendChild(fillingLayer);
|
|
267
|
+
const borderLayer = document.createElement("div");
|
|
268
|
+
borderLayer.className = cursorStyles.cursorBorder;
|
|
269
|
+
this.#cursor.appendChild(borderLayer);
|
|
270
|
+
this.wrapper.appendChild(this.#cursor);
|
|
271
|
+
}
|
|
272
|
+
#moveCursorToTarget() {
|
|
273
|
+
if (this.#disposed) return;
|
|
274
|
+
const newX = this.#currentCursorX + (this.#targetCursorX - this.#currentCursorX) * 0.2;
|
|
275
|
+
const newY = this.#currentCursorY + (this.#targetCursorY - this.#currentCursorY) * 0.2;
|
|
276
|
+
const xDistance = Math.abs(newX - this.#targetCursorX);
|
|
277
|
+
if (xDistance > 0) {
|
|
278
|
+
if (xDistance < 2) {
|
|
279
|
+
this.#currentCursorX = this.#targetCursorX;
|
|
280
|
+
} else {
|
|
281
|
+
this.#currentCursorX = newX;
|
|
282
|
+
}
|
|
283
|
+
this.#cursor.style.left = `${this.#currentCursorX}px`;
|
|
284
|
+
}
|
|
285
|
+
const yDistance = Math.abs(newY - this.#targetCursorY);
|
|
286
|
+
if (yDistance > 0) {
|
|
287
|
+
if (yDistance < 2) {
|
|
288
|
+
this.#currentCursorY = this.#targetCursorY;
|
|
289
|
+
} else {
|
|
290
|
+
this.#currentCursorY = newY;
|
|
291
|
+
}
|
|
292
|
+
this.#cursor.style.top = `${this.#currentCursorY}px`;
|
|
293
|
+
}
|
|
294
|
+
requestAnimationFrame(() => this.#moveCursorToTarget());
|
|
295
|
+
}
|
|
277
296
|
setCursorPosition(x, y) {
|
|
278
|
-
|
|
279
|
-
|
|
297
|
+
if (this.#disposed) return;
|
|
298
|
+
this.#targetCursorX = x;
|
|
299
|
+
this.#targetCursorY = y;
|
|
280
300
|
}
|
|
281
301
|
triggerClickAnimation() {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
302
|
+
if (this.#disposed) return;
|
|
303
|
+
this.#cursor.classList.remove(cursorStyles.clicking);
|
|
304
|
+
void this.#cursor.offsetHeight;
|
|
305
|
+
this.#cursor.classList.add(cursorStyles.clicking);
|
|
285
306
|
}
|
|
286
307
|
show() {
|
|
287
|
-
if (this.shown) return;
|
|
308
|
+
if (this.shown || this.#disposed) return;
|
|
288
309
|
this.shown = true;
|
|
289
310
|
this.motion?.start();
|
|
290
311
|
this.motion?.fadeIn();
|
|
291
312
|
this.wrapper.classList.add(styles.visible);
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
313
|
+
this.#currentCursorX = window.innerWidth / 2;
|
|
314
|
+
this.#currentCursorY = window.innerHeight / 2;
|
|
315
|
+
this.#targetCursorX = this.#currentCursorX;
|
|
316
|
+
this.#targetCursorY = this.#currentCursorY;
|
|
317
|
+
this.#cursor.style.left = `${this.#currentCursorX}px`;
|
|
318
|
+
this.#cursor.style.top = `${this.#currentCursorY}px`;
|
|
298
319
|
}
|
|
299
320
|
hide() {
|
|
300
|
-
if (!this.shown) return;
|
|
321
|
+
if (!this.shown || this.#disposed) return;
|
|
301
322
|
this.shown = false;
|
|
302
323
|
this.motion?.fadeOut();
|
|
303
324
|
this.motion?.pause();
|
|
304
|
-
|
|
325
|
+
this.#cursor.classList.remove(cursorStyles.clicking);
|
|
305
326
|
setTimeout(() => {
|
|
306
327
|
this.wrapper.classList.remove(styles.visible);
|
|
307
328
|
}, 800);
|
|
308
329
|
}
|
|
309
330
|
dispose() {
|
|
331
|
+
this.#disposed = true;
|
|
310
332
|
console.log("dispose SimulatorMask");
|
|
311
333
|
this.motion?.dispose();
|
|
312
334
|
this.wrapper.remove();
|
|
313
335
|
this.dispatchEvent(new Event("dispose"));
|
|
314
336
|
}
|
|
315
|
-
}
|
|
316
|
-
_cursor = new WeakMap();
|
|
317
|
-
_currentCursorX = new WeakMap();
|
|
318
|
-
_currentCursorY = new WeakMap();
|
|
319
|
-
_targetCursorX = new WeakMap();
|
|
320
|
-
_targetCursorY = new WeakMap();
|
|
321
|
-
_SimulatorMask_instances = new WeakSet();
|
|
322
|
-
createCursor_fn = /* @__PURE__ */ __name(function() {
|
|
323
|
-
__privateGet(this, _cursor).className = cursorStyles.cursor;
|
|
324
|
-
const rippleContainer = document.createElement("div");
|
|
325
|
-
rippleContainer.className = cursorStyles.cursorRipple;
|
|
326
|
-
__privateGet(this, _cursor).appendChild(rippleContainer);
|
|
327
|
-
const fillingLayer = document.createElement("div");
|
|
328
|
-
fillingLayer.className = cursorStyles.cursorFilling;
|
|
329
|
-
__privateGet(this, _cursor).appendChild(fillingLayer);
|
|
330
|
-
const borderLayer = document.createElement("div");
|
|
331
|
-
borderLayer.className = cursorStyles.cursorBorder;
|
|
332
|
-
__privateGet(this, _cursor).appendChild(borderLayer);
|
|
333
|
-
this.wrapper.appendChild(__privateGet(this, _cursor));
|
|
334
|
-
}, "#createCursor");
|
|
335
|
-
moveCursorToTarget_fn = /* @__PURE__ */ __name(function() {
|
|
336
|
-
const newX = __privateGet(this, _currentCursorX) + (__privateGet(this, _targetCursorX) - __privateGet(this, _currentCursorX)) * 0.2;
|
|
337
|
-
const newY = __privateGet(this, _currentCursorY) + (__privateGet(this, _targetCursorY) - __privateGet(this, _currentCursorY)) * 0.2;
|
|
338
|
-
const xDistance = Math.abs(newX - __privateGet(this, _targetCursorX));
|
|
339
|
-
if (xDistance > 0) {
|
|
340
|
-
if (xDistance < 2) {
|
|
341
|
-
__privateSet(this, _currentCursorX, __privateGet(this, _targetCursorX));
|
|
342
|
-
} else {
|
|
343
|
-
__privateSet(this, _currentCursorX, newX);
|
|
344
|
-
}
|
|
345
|
-
__privateGet(this, _cursor).style.left = `${__privateGet(this, _currentCursorX)}px`;
|
|
346
|
-
}
|
|
347
|
-
const yDistance = Math.abs(newY - __privateGet(this, _targetCursorY));
|
|
348
|
-
if (yDistance > 0) {
|
|
349
|
-
if (yDistance < 2) {
|
|
350
|
-
__privateSet(this, _currentCursorY, __privateGet(this, _targetCursorY));
|
|
351
|
-
} else {
|
|
352
|
-
__privateSet(this, _currentCursorY, newY);
|
|
353
|
-
}
|
|
354
|
-
__privateGet(this, _cursor).style.top = `${__privateGet(this, _currentCursorY)}px`;
|
|
355
|
-
}
|
|
356
|
-
requestAnimationFrame(() => __privateMethod(this, _SimulatorMask_instances, moveCursorToTarget_fn).call(this));
|
|
357
|
-
}, "#moveCursorToTarget");
|
|
358
|
-
__name(_SimulatorMask, "SimulatorMask");
|
|
359
|
-
let SimulatorMask = _SimulatorMask;
|
|
337
|
+
}
|
|
360
338
|
export {
|
|
361
339
|
SimulatorMask
|
|
362
340
|
};
|
|
363
|
-
//# sourceMappingURL=SimulatorMask-
|
|
341
|
+
//# sourceMappingURL=SimulatorMask-BfJiQVCo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SimulatorMask-BfJiQVCo.js","sources":["../../src/mask/checkDarkMode.ts","../../src/mask/SimulatorMask.ts"],"sourcesContent":["/**\n * Checks for common dark mode CSS classes on the html or body elements.\n * @returns {boolean} - True if a common dark mode class is found.\n */\nfunction hasDarkModeClass() {\n\tconst DEFAULT_DARK_MODE_CLASSES = ['dark', 'dark-mode', 'theme-dark', 'night', 'night-mode']\n\n\tconst htmlElement = document.documentElement\n\tconst bodyElement = document.body || document.documentElement // can be null in some cases\n\n\t// Check class names on <html> and <body>\n\tfor (const className of DEFAULT_DARK_MODE_CLASSES) {\n\t\tif (htmlElement.classList.contains(className) || bodyElement?.classList.contains(className)) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\t// Some sites use data attributes\n\tconst darkThemeAttribute = htmlElement.getAttribute('data-theme')\n\tif (darkThemeAttribute?.toLowerCase().includes('dark')) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n/**\n * Parses an RGB or RGBA color string and returns an object with r, g, b properties.\n * @param {string} colorString - e.g., \"rgb(34, 34, 34)\" or \"rgba(0, 0, 0, 0.5)\"\n * @returns {{r: number, g: number, b: number}|null}\n */\nfunction parseRgbColor(colorString: string) {\n\tconst rgbMatch = /rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/.exec(colorString)\n\tif (!rgbMatch) {\n\t\treturn null // Not a valid rgb/rgba string\n\t}\n\treturn {\n\t\tr: parseInt(rgbMatch[1]),\n\t\tg: parseInt(rgbMatch[2]),\n\t\tb: parseInt(rgbMatch[3]),\n\t}\n}\n\n/**\n * Determines if a color is \"dark\" based on its calculated luminance.\n * @param {string} colorString - The CSS color string (e.g., \"rgb(50, 50, 50)\").\n * @param {number} threshold - A value between 0 and 255. Colors with luminance below this will be considered dark. Default is 128.\n * @returns {boolean} - True if the color is considered dark.\n */\nfunction isColorDark(colorString: string, threshold = 128) {\n\tif (!colorString || colorString === 'transparent' || colorString.startsWith('rgba(0, 0, 0, 0)')) {\n\t\treturn false // Transparent is not dark\n\t}\n\n\tconst rgb = parseRgbColor(colorString)\n\tif (!rgb) {\n\t\treturn false // Could not parse color\n\t}\n\n\t// Calculate perceived luminance using the standard formula\n\tconst luminance = 0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b\n\n\treturn luminance < threshold\n}\n\n/**\n * Checks the background color of the body element to determine if the page is dark.\n * @returns {boolean}\n */\nfunction isBackgroundDark() {\n\t// We check both <html> and <body> because some pages set the color on <html>\n\tconst htmlStyle = window.getComputedStyle(document.documentElement)\n\tconst bodyStyle = window.getComputedStyle(document.body || document.documentElement)\n\n\t// Get background colors\n\tconst htmlBgColor = htmlStyle.backgroundColor\n\tconst bodyBgColor = bodyStyle.backgroundColor\n\n\t// The body's background might be transparent, in which case we should\n\t// fall back to the html element's background.\n\tif (isColorDark(bodyBgColor)) {\n\t\treturn true\n\t} else if (bodyBgColor === 'transparent' || bodyBgColor.startsWith('rgba(0, 0, 0, 0)')) {\n\t\treturn isColorDark(htmlBgColor)\n\t}\n\n\treturn false\n}\n\n/**\n * A comprehensive function to determine if the page is currently in a dark theme.\n * It combines class checking and background color analysis.\n * @returns {boolean} - True if the page is likely dark.\n */\nexport function isPageDark() {\n\ttry {\n\t\t// Strategy 1: Check for common dark mode classes\n\t\tif (hasDarkModeClass()) {\n\t\t\treturn true\n\t\t}\n\n\t\t// Strategy 2: Analyze the computed background color\n\t\tif (isBackgroundDark()) {\n\t\t\treturn true\n\t\t}\n\n\t\t// @TODO add more checks here, e.g., analyzing text color,\n\t\t// or checking the background of major layout elements like <main> or #app.\n\n\t\treturn false\n\t} catch (error) {\n\t\tconsole.warn('Error determining if page is dark:', error)\n\t\treturn false\n\t}\n}\n","import { Motion } from 'ai-motion'\n\nimport { isPageDark } from './checkDarkMode'\n\nimport styles from './SimulatorMask.module.css'\nimport cursorStyles from './cursor.module.css'\n\nexport class SimulatorMask extends EventTarget {\n\tshown: boolean = false\n\twrapper = document.createElement('div')\n\tmotion: Motion | null = null\n\n\t#disposed = false\n\n\t#cursor = document.createElement('div')\n\n\t#currentCursorX = 0\n\t#currentCursorY = 0\n\n\t#targetCursorX = 0\n\t#targetCursorY = 0\n\n\tconstructor() {\n\t\tsuper()\n\n\t\tthis.wrapper.id = 'page-agent-runtime_simulator-mask'\n\t\tthis.wrapper.className = styles.wrapper\n\t\tthis.wrapper.setAttribute('data-browser-use-ignore', 'true')\n\t\tthis.wrapper.setAttribute('data-page-agent-ignore', 'true')\n\n\t\ttry {\n\t\t\tconst motion = new Motion({\n\t\t\t\tmode: isPageDark() ? 'dark' : 'light',\n\t\t\t\tstyles: { position: 'absolute', inset: '0' },\n\t\t\t})\n\t\t\tthis.motion = motion\n\t\t\tthis.wrapper.appendChild(motion.element)\n\t\t\tmotion.autoResize(this.wrapper)\n\t\t} catch (e) {\n\t\t\tconsole.warn('[SimulatorMask] Motion overlay unavailable:', e)\n\t\t}\n\n\t\t// Capture all mouse, keyboard, and wheel events\n\t\tthis.wrapper.addEventListener('click', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\t\tthis.wrapper.addEventListener('mousedown', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\t\tthis.wrapper.addEventListener('mouseup', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\t\tthis.wrapper.addEventListener('mousemove', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\t\tthis.wrapper.addEventListener('wheel', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\t\tthis.wrapper.addEventListener('keydown', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\t\tthis.wrapper.addEventListener('keyup', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\n\t\t// Create AI cursor\n\t\tthis.#createCursor()\n\t\t// this.show()\n\n\t\tdocument.body.appendChild(this.wrapper)\n\n\t\tthis.#moveCursorToTarget()\n\n\t\t// global events\n\t\t// @note Mask should be isolated from the rest of the code.\n\t\t// Global events are easier to manage and cleanup.\n\n\t\tconst movePointerToListener = (event: Event) => {\n\t\t\tconst { x, y } = (event as CustomEvent).detail\n\t\t\tthis.setCursorPosition(x, y)\n\t\t}\n\t\tconst clickPointerListener = () => {\n\t\t\tthis.triggerClickAnimation()\n\t\t}\n\t\tconst enablePassThroughListener = () => {\n\t\t\tthis.wrapper.style.pointerEvents = 'none'\n\t\t}\n\t\tconst disablePassThroughListener = () => {\n\t\t\tthis.wrapper.style.pointerEvents = 'auto'\n\t\t}\n\n\t\twindow.addEventListener('PageAgent::MovePointerTo', movePointerToListener)\n\t\twindow.addEventListener('PageAgent::ClickPointer', clickPointerListener)\n\t\twindow.addEventListener('PageAgent::EnablePassThrough', enablePassThroughListener)\n\t\twindow.addEventListener('PageAgent::DisablePassThrough', disablePassThroughListener)\n\n\t\tthis.addEventListener('dispose', () => {\n\t\t\twindow.removeEventListener('PageAgent::MovePointerTo', movePointerToListener)\n\t\t\twindow.removeEventListener('PageAgent::ClickPointer', clickPointerListener)\n\t\t\twindow.removeEventListener('PageAgent::EnablePassThrough', enablePassThroughListener)\n\t\t\twindow.removeEventListener('PageAgent::DisablePassThrough', disablePassThroughListener)\n\t\t})\n\t}\n\n\t#createCursor() {\n\t\tthis.#cursor.className = cursorStyles.cursor\n\n\t\t// Create ripple effect container\n\t\tconst rippleContainer = document.createElement('div')\n\t\trippleContainer.className = cursorStyles.cursorRipple\n\t\tthis.#cursor.appendChild(rippleContainer)\n\n\t\t// Create filling layer\n\t\tconst fillingLayer = document.createElement('div')\n\t\tfillingLayer.className = cursorStyles.cursorFilling\n\t\tthis.#cursor.appendChild(fillingLayer)\n\n\t\t// Create border layer\n\t\tconst borderLayer = document.createElement('div')\n\t\tborderLayer.className = cursorStyles.cursorBorder\n\t\tthis.#cursor.appendChild(borderLayer)\n\n\t\tthis.wrapper.appendChild(this.#cursor)\n\t}\n\n\t#moveCursorToTarget() {\n\t\tif (this.#disposed) return\n\n\t\tconst newX = this.#currentCursorX + (this.#targetCursorX - this.#currentCursorX) * 0.2\n\t\tconst newY = this.#currentCursorY + (this.#targetCursorY - this.#currentCursorY) * 0.2\n\n\t\tconst xDistance = Math.abs(newX - this.#targetCursorX)\n\t\tif (xDistance > 0) {\n\t\t\tif (xDistance < 2) {\n\t\t\t\tthis.#currentCursorX = this.#targetCursorX\n\t\t\t} else {\n\t\t\t\tthis.#currentCursorX = newX\n\t\t\t}\n\t\t\tthis.#cursor.style.left = `${this.#currentCursorX}px`\n\t\t}\n\n\t\tconst yDistance = Math.abs(newY - this.#targetCursorY)\n\t\tif (yDistance > 0) {\n\t\t\tif (yDistance < 2) {\n\t\t\t\tthis.#currentCursorY = this.#targetCursorY\n\t\t\t} else {\n\t\t\t\tthis.#currentCursorY = newY\n\t\t\t}\n\t\t\tthis.#cursor.style.top = `${this.#currentCursorY}px`\n\t\t}\n\n\t\trequestAnimationFrame(() => this.#moveCursorToTarget())\n\t}\n\n\tsetCursorPosition(x: number, y: number) {\n\t\tif (this.#disposed) return\n\n\t\tthis.#targetCursorX = x\n\t\tthis.#targetCursorY = y\n\t}\n\n\ttriggerClickAnimation() {\n\t\tif (this.#disposed) return\n\n\t\tthis.#cursor.classList.remove(cursorStyles.clicking)\n\t\t// Force reflow to restart animation\n\t\tvoid this.#cursor.offsetHeight\n\t\tthis.#cursor.classList.add(cursorStyles.clicking)\n\t}\n\n\tshow() {\n\t\tif (this.shown || this.#disposed) return\n\n\t\tthis.shown = true\n\t\tthis.motion?.start()\n\t\tthis.motion?.fadeIn()\n\n\t\tthis.wrapper.classList.add(styles.visible)\n\n\t\t// Initialize cursor position\n\t\tthis.#currentCursorX = window.innerWidth / 2\n\t\tthis.#currentCursorY = window.innerHeight / 2\n\t\tthis.#targetCursorX = this.#currentCursorX\n\t\tthis.#targetCursorY = this.#currentCursorY\n\t\tthis.#cursor.style.left = `${this.#currentCursorX}px`\n\t\tthis.#cursor.style.top = `${this.#currentCursorY}px`\n\t}\n\n\thide() {\n\t\tif (!this.shown || this.#disposed) return\n\n\t\tthis.shown = false\n\t\tthis.motion?.fadeOut()\n\t\tthis.motion?.pause()\n\n\t\tthis.#cursor.classList.remove(cursorStyles.clicking)\n\n\t\tsetTimeout(() => {\n\t\t\tthis.wrapper.classList.remove(styles.visible)\n\t\t}, 800) // Match the animation duration\n\t}\n\n\tdispose() {\n\t\tthis.#disposed = true\n\t\tconsole.log('dispose SimulatorMask')\n\t\tthis.motion?.dispose()\n\t\tthis.wrapper.remove()\n\t\tthis.dispatchEvent(new Event('dispose'))\n\t}\n}\n"],"names":[],"mappings":"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"}
|