Commit Graph
9542 Commits
Author SHA1 Message Date
Karl Seguin 89c217c610 indexeddb: serialize value at entry
When writing a value, we used to store js.Value.Global in the transaction's
queue and then serialize it at write-time. We're supposed to capture the value
at call-time. The result is that, if JS code alters the value, we can end up
storing the wrong value. We now serialize the value at call time, so that any
subsequent changes to the value are not captured by the operation.

Also improve how we map large integers. Because JavaScript can't represent the
full u64/i64, we need to treat large numbers as floats and truncate. This is
done both from JS -> Zig and from Zig -> JS.
2026-08-31 16:24:03 +08:00
Karl Seguin 7dd4496b0f cli: add --http-version 1.1 / auto flag
https://github.com/lightpanda-io/browser/issues/3348

When set to 1.1, libcurl is configured to only offer HTTP 1.1. By default, or
when set to "auto", it's up to libcurl to decide how to connect. This maps to
libcurl's CURL_HTTP_VERSION_1_1 and CURL_HTTP_VERSION_NONE.

LP.configureCDP now takes an `httpVersion` field which can be "1.1" or "auto"
to control that specific browser session. Ideally this is called prior to any
navigation.
2026-08-31 16:16:47 +08:00
Rohit d6952ec5a4 refactor(webapi): remove unused MediaError.init
MediaError.init had no caller and MediaError has no JS constructor
exposed (new MediaError() is not valid JS), so the helper was
unreachable dead code. It also had a latent bug: it passed a struct
VALUE to std.mem.Allocator.create, which expects a TYPE. That bug
never surfaced because Zig lazily skips analyzing unreferenced
function bodies.

Remove init per maintainer review, along with its now-unused Frame
import. HTMLMediaElement.error still returns null today, so this
does not change runtime behavior.

Verified: zig fmt --check clean, scoped build+test green (1 of 1,
the remaining constants test).
2026-08-31 13:44:58 +05:30
Adrià Arrufat 95e8dfa400 browser: make resolveTargetFrame's _blank explicit; submit target=_blank forms into a popup
resolveTargetFrame returned null for _blank, so every caller carried the
meaning of that null. It now returns a tagged union and callsites switch
on it. <form target=_blank> takes the same path as links: the popup is
opened only once the submission is going ahead, so validation or
preventDefault can't leave a stray window. The opener rule (withheld
unless rel=opener) lives in one Frame.openBlankTarget helper.

awaitQueuedNavigation took a frame id, but Runner waits are keyed by
Page root, so a followed popup's id resolved to FrameNotFound and every
navigation from inside a popup failed. It now takes the Frame and waits
on its Page root, read before processing since a synthetic root
navigation frees the Page in place.
2026-08-31 09:32:59 +02:00
Karl Seguin c8c54f2067 minor: remove potentially wasteful id dupe on removeId
We currently unconditionally dupe the remove_ids key. But it _could_ already
exist in the map. Swapping the unconditional put with a getOrPut.
2026-08-31 14:55:43 +08:00
Karl Seguin 482d0951a0 render: clientHeight/clientWidth returns the viewport for the body
Meant to improve https://github.com/lightpanda-io/browser/issues/3251

There's a script on taobao and tmall which tries to tile the visible porition
or the root element. Well, the root element's fake height is 100,000,000 so the
page stalls.

This changes is so that the body's clientHeight/Width returns the viewport
dimensions.
2026-08-31 12:37:37 +08:00
Karl Seguin fad4b97079 Merge pull request #3343 from staylor/fix/errored-module-reimport
js: reject module evaluation before instantiation
2026-08-31 12:24:08 +08:00
Karl Seguin 1d813f7602 Merge pull request #3345 from lightpanda-io/robots-telemetry
telemetry: track if --obey-robots is used
2026-08-31 12:21:00 +08:00
Karl Seguin a0718e0d2a Continue to fail in DEBUG
Log err in release.
2026-08-31 11:41:45 +08:00
Karl Seguin dfaf8679c5 Merge pull request #3342 from staylor/fix/macos-framework-sdk
build: honor macOS SDK root for frameworks
2026-08-31 08:51:51 +08:00
Karl Seguin fdd092bb2e Merge pull request #3333 from lightpanda-io/markdown-flex-separators
markdown: separate flex and grid items in the dump
2026-08-31 07:55:40 +08:00
Karl Seguin e7e160f39b Merge pull request #3344 from lightpanda-io/fix-readablestream-cross-context
crash: fix null dereference when ReadableStream is used cross-context
2026-08-31 07:53:36 +08:00
Adrià Arrufat 24bf00cf3b markdown: optimize element rendering by removing duplicate checks 2026-08-30 21:38:25 +02:00
Ramiro_quai 3e8ff142ef fix(actions): click dispatches full pointer/mouse sequence, not a bare click event
actions.click() previously dispatched a single untrusted-shaped "click"
MouseEvent directly on the target node, skipping pointerdown, mousedown,
pointerup, and mouseup entirely. Many real-world widgets — custom
autocomplete/combobox components in particular — open or otherwise react
on mousedown, not click alone, so this made them unreachable through the
click tool even though the element was correctly focused and targeted.

WebDriver.zig's own click() already implements the correct sequence
(pointerdown, mousedown, pointerup, mouseup, click) for testdriver's
click, with a comment explicitly contrasting it against a lone untrusted
click event. This change ports that same sequence into actions.click()
so the MCP/CDP "click" action produces the same event sequence a real
user click would.

Adds a mousedown assertion to the existing MCP Actions test
(mcp_actions.html + tools.zig) to catch a regression here; confirmed the
new assertion fails against the old implementation and passes against
this one. Full test suite (1339 tests) and zig fmt --check both pass.

Reproduced against a real, previously-untested production site
(a Wix-built autocomplete branch-selector widget) where click could
focus the input but never open its option list; a minimal local
reproduction (a mousedown-only widget) confirms the fix.
2026-08-30 04:32:17 -06:00
Karl Seguin e00108260f telemetry: track if --obey-robots is used
Re-purposes the "proxy" integer as a CLI bitmask flag. Requires a server update.
2026-08-30 14:10:40 +08:00
Karl Seguin 983950a75a crash: fix null dereference when ReadableStream is used cross-context
ReadableStream's assumed collectBodyBytes was being called on the same context
that it was created, so that in a cross-context call, the expected LocalScope
was null. This creates an explicit local scope.

Fixes crash on WPT /service-workers/service-worker/fetch-event.https.h2.html
2026-08-30 11:32:22 +08:00
Scott Taylor 05a56ece91 js: reject module evaluation before instantiation
Assisted-By: devx/6fc48df3-67c4-46f2-9e14-98e4ac4bc21d
2026-08-29 12:53:19 -04:00
Scott Taylor 8072fc0827 build: honor macOS SDK root for frameworks
Assisted-By: devx/6fc48df3-67c4-46f2-9e14-98e4ac4bc21d
2026-08-29 12:28:29 -04:00
Karl Seguin 27831c20bf Merge pull request #3341 from lightpanda-io/remove-debug-unknown-property
debug: remove unknown property logging
2026-08-29 17:18:30 +08:00
Karl Seguin 78a96ff0aa Merge pull request #3340 from lightpanda-io/remove-cdp-runtime-log
chore: remove debug-only CDP runtime disk-logging
2026-08-29 17:18:22 +08:00
Karl Seguin 9f68f0314c Merge pull request #3338 from lightpanda-io/xhr-blog-content-type
webapi: Report correct content-type for blob
2026-08-29 17:18:11 +08:00
Karl Seguin ed949ebbfc Merge pull request #3337 from lightpanda-io/fix-element-unsafe-cast
crash: fix unsafe element cast
2026-08-29 17:18:00 +08:00
Karl Seguin 5d5459fc8b Merge pull request #3339 from lightpanda-io/lower-MAX_VmHWM
CI: Lower MAX_VmHWM to 24 (down from 28)
2026-08-29 12:32:48 +08:00
Karl Seguin eabc865338 debug: remove unknown property logging
Commented it out for now, but plan on remove the code at some point in the
future. This was useful when sites would break because of an unimplemented
API, but (a) those are rare now and (b) AI is good at finding issues without
this. As-is, it just makes --log-level debug useless in Debug builds. The
logging could never tell between an site-specific global and a real API, and
sites have _a lot_ of globals, so it's a lot of noise.
2026-08-29 12:01:00 +08:00
Karl Seguin 28180bc9df chore: remove debug-only CDP runtime disk-logging 2026-08-29 11:56:18 +08:00
Karl Seguin 313803c354 CI: Lower MAX_VmHWM to 24 (down from 28)
orderfile PRs (https://github.com/lightpanda-io/browser/pull/3271 and
https://github.com/lightpanda-io/browser/pull/3285) has dropped memory usage to
~23.6. Rather than hitting 28MB in 2-3 months time and not knowing how we got
there, I'd rather get slow/incremental notices.
2026-08-29 11:41:12 +08:00
Karl Seguin 36654e1587 webapi: Report correct content-type for blob
https://github.com/lightpanda-io/browser/pull/3320 made Mime.zig aware of
`application/octet-stream`, but Mime is still lossy, e.g.
"text/html; charset=utf-8" -> "text/html".

This commit dupes the response's content-type in the XHR's arena and use that
value as-is.
2026-08-29 11:26:13 +08:00
Karl Seguin 5c0ad869a5 crash: fix unsafe element cast
.unknown can map to either an Svg.Unknown or Html.Unknown. The dump was assuming
HTML when doing a void-tag check, but we can skip the entire issue here since
only HTML has void tags.
2026-08-29 11:16:24 +08:00
Karl Seguin dd2669ade6 Merge pull request #3326 from lightpanda-io/cdp-emulation-stubs
cdp: accept the emulation and setup calls drivers send at context creation
2026-08-29 11:01:09 +08:00
Karl Seguin 156af13d61 Merge pull request #3320 from lightpanda-io/mime-octet-stream
`application/octet-stream` in Mime for Blob
2026-08-29 10:53:32 +08:00
Karl Seguin 37af405076 sync protocol.json 2026-08-29 10:48:36 +08:00
Adrià Arrufat 06167f7a88 cdp: accept the emulation and setup calls drivers send at context creation
Emulation.setLocaleOverride, setTimezoneOverride, setScriptExecutionDisabled,
setDefaultBackgroundColorOverride, Page.setBypassCSP, bringToFront,
setInterceptFileChooserDialog, Network.emulateNetworkConditions and
setBypassServiceWorker returned UnknownMethod. The ones that already hold
(no CSP, one page, no service workers, no file chooser, no background)
are plain no-ops; locale and timezone are accepted with a warning;
disabling script execution and offline emulation return a clear error.
2026-08-29 10:40:14 +08:00
Karl Seguin e3f47c7ed9 Merge pull request #3325 from lightpanda-io/cdp-runtime-passthrough
cdp: pass more Runtime methods through to the inspector
2026-08-29 10:34:07 +08:00
Karl Seguin 2fb1629d05 update protocol.json 2026-08-29 09:48:21 +08:00
Karl Seguin 1bd957d076 Merge pull request #3323 from lightpanda-io/cdp-boxmodel-quads
cdp: fill all DOM.getBoxModel quads
2026-08-29 07:12:51 +08:00
Karl Seguin eded004450 Merge pull request #3312 from lightpanda-io/tool-session
mcp: fold Server.Session onto lp.ToolSession, bracket every isolate use
2026-08-29 07:02:32 +08:00
Karl Seguin 186ead045f Merge pull request #3321 from lightpanda-io/pdf
Add PDF support
2026-08-29 07:00:38 +08:00
Adrià Arrufat 4677e707d6 Merge pull request #3311 from lightpanda-io/interactive-axname
interactive: take roles and names from AXNode
2026-08-28 15:38:25 +02:00
Adrià Arrufat 33fcf99d08 test: use testing.expectEqual helper 2026-08-28 15:16:58 +02:00
Adrià Arrufat f1bdd0019f Merge branch 'main' into tool-session 2026-08-28 15:14:56 +02:00
Adrià Arrufat 0dd230fb45 interactive: only fall back to text content for role-less elements
The bare orelse gave text-content names to roled elements the AX tree
leaves unnamed (select, textarea, details). Scope the fallback to
listener/tabindex-only elements, where AccName gives nothing and the
text is the agent's only handle.
2026-08-28 15:12:00 +02:00
Adrià Arrufat ad15869b41 cdp: fill all DOM.getBoxModel quads
padding, border and margin were zeroed. Playwright reads `border` for
boundingBox(), so every element reported {0,0,0,0}. Without padding,
border or margin in the layout, the four boxes coincide with content.
2026-08-28 14:58:45 +02:00
Adrià Arrufat 81530d8a22 markdown: separate flex and grid items in the dump
Children of a `display: flex`/`grid` container are separate boxes however
inline their tags are, so `Title<b>Aug 04 2026</b>` inside a flex `<a>` ran
together as `Title**Aug 04 2026**`. StyleManager now keeps the display kind
(none/flex/grid/other) instead of a display:none bool, and the dumper puts a
space between the rendered items of such a container, skipping the
whitespace between them like layout does.
2026-08-28 14:52:37 +02:00
Adrià Arrufat 2899bfef4a agent: route REPL output per tool and align page tables of any size
Every data command went through printAssistant, so /markdown was styled by
accident while /tree, /getUrl and /evaluate strings had `*`/`_` eaten as
emphasis, and /markdown lost table alignment past Stream's 16 KiB buffer.

- printData renders only markdown as markdown; JSON is re-indented and the
  rest prints verbatim.
- render iterates the source directly and aligns tables from the slice;
  Fence holds the fence state shared with Stream.
- Links are OSC 8 hyperlinks around the label only, with the label
  inline-rendered; `![alt](url)` drops the `!`; escapes follow CommonMark
  so what the page dumper escapes is unescaped.
2026-08-28 14:38:27 +02:00
Karl Seguin 054b0b40ed Merge pull request #3322 from lightpanda-io/fix/agent-js-history
agent: fix agent history in JS mode
2026-08-28 20:35:53 +08:00
Adrià Arrufat 9126fd9540 Merge pull request #3324 from lightpanda-io/cdp-method-not-found
cdp: answer unknown methods with -32601 like Chrome
2026-08-28 13:36:02 +02:00
Adrià Arrufat 96e9ef969a browser: open target=_blank links as popups and let tools follow them
Clicking a target=_blank link was logged and dropped. It now opens a
popup Frame, the same top-level context window.open creates; the opener
is withheld unless rel=opener, per spec.

A popup is invisible to the tool layer, which acts on the root frame, so
finalizeAction snapshots the popup count before the action and, when one
appears, waits for it to load and makes it the session's current frame.
The action result says so. Once the popup is gone, tools fall back to
the root.
2026-08-28 11:23:05 +02:00
Adrià Arrufat 33b3b0ee47 cdp: pass more Runtime methods through to the inspector
The whitelist rejected methods the V8 inspector already implements,
notably releaseObjectGroup, which Puppeteer sends on handle disposal.
Bookkeeping methods that cannot observe or change the page's global
skip the main_world_touched mark.
2026-08-28 10:35:36 +02:00
Adrià Arrufat 9a64780c10 cdp: answer unknown methods with -32601 like Chrome
Unknown domains and methods returned our private -31998 with the Zig
error name. Drivers feature-detect on Chrome's -32601 "'X' wasn't
found", so return that; other dispatch errors keep -31998.
2026-08-28 09:33:32 +02:00
Adrià Arrufat 0d1e3c0c8b agent: fix agent history in JS mode 2026-08-28 09:07:16 +02:00