1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
import type { BrowserClient } from "../client";
import { type Result, err, ok } from "../util/result";
import type { ToolErr } from "../util/tool";
import { cdpCall } from "./cdp-call";
export type Box = {
readonly x: number;
readonly y: number;
readonly width: number;
readonly height: number;
readonly cx: number;
readonly cy: number;
};
type BoxModel = {
readonly content: ReadonlyArray<number>;
readonly width: number;
readonly height: number;
};
export const centreOf = (model: BoxModel): Box => {
const x = model.content[0] ?? 0;
const y = model.content[1] ?? 0;
return {
x: Math.round(x),
y: Math.round(y),
width: Math.round(model.width),
height: Math.round(model.height),
cx: Math.round(x + model.width / 2),
cy: Math.round(y + model.height / 2),
};
};
export const boxOf = async (
client: BrowserClient,
backendNodeId: number,
): Promise<Result<Box, ToolErr>> => {
const r = await cdpCall(client, "DOM.getBoxModel", { backendNodeId });
if (!r.success) return r;
const model = r.data.model;
if (model.content.length < 8) {
return err({ kind: "invalid_state", message: "DOM.getBoxModel returned an incomplete content quad" });
}
if (model.width <= 0 || model.height <= 0) {
return err({
kind: "invalid_state",
message: "element has a zero-size box and cannot be clicked",
});
}
return ok(centreOf(model));
};
|