aboutsummaryrefslogtreecommitdiff
path: root/src/domains/box.ts
diff options
context:
space:
mode:
authoramankumarsingh77 <amankumarsingh7702@gmail.com>2026-07-27 23:26:50 +0530
committerAman Kumar <145339995+amankumarsingh77@users.noreply.github.com>2026-08-02 19:12:46 +0530
commit9f2f75dd9281153888776e5d39d4926655c15f2a (patch)
tree89c23c8ad333b5096d39b661b142eaad544cf004 /src/domains/box.ts
parent931576443dcb990761cb7e68e354465145f9292d (diff)
refactor(domains): drop CDP casts, share the box-model unwrap
ref-resolve.ts and snapshot.ts had the same box-model unwrap, both using data.model! to work around an untyped response. Extracted to domains/box.ts; the typed schema makes the assertions unnecessary. Both derived the centre identically (quad corner + half the model width/height), so centreOf keeps that derivation; the shared zero-size rejection moved into boxOf, and snapshot keeps its own off-viewport (x/y < 0) filter. evalInIsolatedTab now goes through evaluateJson with the tab's own sessionId and a caller-supplied guard; both callers evaluate expressions ending in JSON.stringify, so they pass isJsonText rather than a check that checks nothing. Runtime.evaluate/callFunctionOn result casts in form.ts, forms.ts and keyboard.ts are replaced by named guards over the in-page result shapes. Runtime.callFunctionOn's params schema gained arguments/returnByValue/ awaitPromise/userGesture: four domain call sites legitimately pass them and typebox's additionalProperties:true does not widen the static type, so the params type was rejecting valid CDP fields. Params schemas are type-only (only results are compiled), so this is a compile-time widening with no runtime effect. tsc is green again for both tsconfigs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'src/domains/box.ts')
-rw-r--r--src/domains/box.ts47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/domains/box.ts b/src/domains/box.ts
new file mode 100644
index 0000000..7b12e82
--- /dev/null
+++ b/src/domains/box.ts
@@ -0,0 +1,47 @@
+import type { BrowserClient } from "../client";
+import { type Result, err, ok } from "../util/result";
+import type { ToolErr } from "../util/tool";
+
+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 client.session().call("DOM.getBoxModel", { backendNodeId });
+ if (!r.success) return err({ kind: "cdp_error", message: r.error.message });
+ 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));
+};