diff options
| author | amankumarsingh77 <amankumarsingh7702@gmail.com> | 2026-07-27 23:26:50 +0530 |
|---|---|---|
| committer | Aman Kumar <145339995+amankumarsingh77@users.noreply.github.com> | 2026-08-02 19:12:46 +0530 |
| commit | 9f2f75dd9281153888776e5d39d4926655c15f2a (patch) | |
| tree | 89c23c8ad333b5096d39b661b142eaad544cf004 /src/domains/box.ts | |
| parent | 931576443dcb990761cb7e68e354465145f9292d (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.ts | 47 |
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)); +}; |
