src/domains/box.ts (view raw)
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));
};
|