Commit Graph
9542 Commits
Author SHA1 Message Date
Pierre TachoireandAdrià Arrufat 056cd3261f Update src/browser/webapi/css/CSSStyleDeclaration.zig
Co-authored-by: Adrià Arrufat <1671644+arrufat@users.noreply.github.com>
2026-06-30 15:01:27 +02:00
Karl Seguin 87b93faf91 minor: ignore test server error when writing internal server error 2026-06-30 20:40:36 +08:00
Adrià Arrufat 1dd5f6548d agent: update script instructions for parallel pages
Updates the `script_skill` prompt to recommend and demonstrate parallel
page navigation using `Promise.all` and multiple `Page` instances,
rather than serial navigation on a single page.
2026-06-30 13:27:54 +02:00
Adrià Arrufat 3a01114745 CDP: evict only replaced page nodes on re-goto
Introduce `Registry.resetFrame` to selectively evict nodes owned by
the replaced page's frame. This prevents invalidating node IDs of
sibling pages during concurrent navigations.
2026-06-30 09:39:46 +02:00
Adrià Arrufat 8a2bf904c2 Merge branch 'main' into agent-async-goto-parallel-navigation 2026-06-30 09:29:15 +02:00
Pierre Tachoire 6f453e0949 Merge pull request #2846 from lightpanda-io/ci-read-pkg
ci: add read permission to release for docker
2026-06-30 08:53:45 +02:00
Pierre Tachoire 7aa8bac4ba ci: add read permission to release for docker 2026-06-30 08:31:15 +02:00
Karl Seguin 1f8076b8be Merge pull request #2834 from lightpanda-io/update-v8
Update v8
2026-06-30 13:58:58 +08:00
Karl Seguin d2f72dfd4b update v8 version 2026-06-30 13:39:13 +08:00
Karl Seguin 98157e18ab update zig-v8-fork dep 2026-06-30 13:36:02 +08:00
Karl Seguin fc4932508c Merge pull request #2845 from lightpanda-io/slience_test_log
minor: silence log in test that intentionally generates an error
2026-06-30 13:15:05 +08:00
Karl Seguin 459daecbea zig fmt 2026-06-30 13:05:51 +08:00
Karl Seguin c754c999a4 minor: silence log in test that intentionally generates an error 2026-06-30 13:04:24 +08:00
Karl Seguin 96e23f78e8 perf: Skip CSSStyleProperty creation if there is no style attribute
Was reviewing https://github.com/lightpanda-io/browser/pull/2836 and realized
the StyleManager's getInlineStyleProperty could be optimized  to avoid creating
the CSSStyleProperties in the case where there's no style attribute.
2026-06-30 12:50:50 +08:00
Navid EMAD 66fb6748bf page: flush deferred transfers after a synchronous stylesheet fetch
Frame.loadExternalStylesheet fetches an external <link rel=stylesheet>
synchronously, which registers a blocking request for the frame. While that
blocking request is active the DeferringLayer holds back the completion
callbacks of every other in-flight transfer for the frame, so they don't run
JS on the parser stack. The blocking-<script> path and the worker path flush
those deferred completions once their synchronous fetch returns, but the
external-stylesheet path did not. As a result a <script defer> that finished
loading during the stylesheet's blocking window stayed at complete == false:
the deferred-script queue never drained, so the deferred scripts never ran and
DOMContentLoaded / the load event / readyState -> "complete" never fired —
the document was stuck at readyState "loading" even though every request
completed with HTTP 200.

Flush the frame's deferring layer after the synchronous stylesheet fetch,
mirroring the other two synchronous-request call sites.

Closes #2842
2026-06-29 21:46:35 +02:00
Pierre Tachoire 0614795fc5 css: resolve computed inline styles via StyleManager
getComputedStyle now reads inline values from the element's parsed
el.style through StyleManager.inlineStyleValue instead of re-parsing the
style= attribute, so computed and inline values share one source of
truth. Move the !important cascade precedence to the shared parse path
(applyParsedDeclaration) so el.style resolves duplicate declarations
correctly too.
2026-06-29 14:37:54 +02:00
Karl Seguin fe3e53c34a Merge pull request #2839 from lightpanda-io/request_interception_redirect
cdp: follow redirects on request interception fulfillment
2026-06-29 16:16:30 +08:00
Karl Seguin 5a65fdbbec Merge pull request #2838 from lightpanda-io/document-cookie
webapi: Fix move cookie accessor from HTMLDocument to Document
2026-06-29 16:16:13 +08:00
Pierre Tachoire ac0a854830 Merge pull request #2840 from lightpanda-io/ci-release-again
ci: login on GH registry during release
2026-06-29 08:12:08 +00:00
Pierre Tachoire cf99ec2fbd Merge pull request #2826 from bebsworthy/fix/cdp-frameattached-double-params
cdp: Fix Page.frameAttached params double-wrapping that broke sub-frame interception
2026-06-29 07:50:25 +00:00
Pierre Tachoire 30eb23e0c5 ci: login on GH registry during release 2026-06-29 09:41:58 +02:00
Pierre Tachoire e396cbb90c ci: login on GH registry during release 2026-06-29 09:38:10 +02:00
Adrià ArrufatandKarl Seguin c6e4715032 script-runtime: use ArrayList
Co-authored-by: Karl Seguin <karlseguin@users.noreply.github.com>
2026-06-29 08:05:05 +02:00
Karl Seguin c40e6c5b94 cdp: follow redirects on request interception fulfillment
Fixes https://github.com/lightpanda-io/browser/issues/2828
2026-06-29 10:48:37 +08:00
Karl Seguin f2dd10a5ae Merge pull request #2827 from bebsworthy/fix/cross-origin-messageevent-source
webapi: Fix cross-origin MessageEvent.source WindowProxy identity
2026-06-29 08:38:44 +08:00
Karl Seguin 3a3ef67ab0 webapi: Fix move cookie accessor from HTMLDocument to Document
Per spec, this should be accessible on the Document, not the HTMLDocument. I
ran into a site that was doing:

Object.getOwnPropertyDescriptor(Document.prototype, "cookie")

and that was failing
2026-06-29 07:31:19 +08:00
Muki Kiboigo f75b6f966b add simple 1 day heuristic cache 2026-06-28 14:09:52 -07:00
Karl Seguin 9faf8c1e75 Merge pull request #2832 from lightpanda-io/update_libcurl_and_nghttp2
dep: update libcurl and nghttp2
2026-06-28 16:40:53 +08:00
Matt Van Horn 16b16564d5 css: honor !important for duplicate inline declarations in computed style 2026-06-27 23:30:46 -07:00
Karl Seguin d9c76d0b0e update zig-v8-fork dep hash 2026-06-28 14:25:13 +08:00
Adrià Arrufat 023c3c25a7 script-runtime: support concurrent page navigations
Changes `page.goto` to return a pending Promise instead of blocking
synchronously. Introduces a driver loop in `Runtime` to tick the
browser and settle pending navigations. This allows parallel gotos
and routes tool calls to their respective frames.
2026-06-28 08:25:03 +02:00
Karl Seguin 8350076972 update intercepted type from u8 to u32 2026-06-28 14:18:12 +08:00
Matt Van Horn 1c044b089b fix: resolve inline style= declarations in getComputedStyle 2026-06-27 23:13:36 -07:00
Karl Seguin d550a89330 v8, dep: Update v8
This update of zig-v8-fork is an update of v8 itself.
2026-06-28 08:03:02 +08:00
Karl Seguin 01ad869dff Merge pull request #2831 from lightpanda-io/unused_imports
minor: remove unused imports
2026-06-28 07:46:43 +08:00
Karl Seguin a362a4e461 Merge pull request #2830 from lightpanda-io/xhr_multi_transfer_guard
fix: Reject xhr send() when send already active
2026-06-28 07:46:32 +08:00
Halil Durak a457ddf8a7 Merge pull request #2703 from lightpanda-io/nikneym/rework-url-resolve
`URL`: Rework `resolve` with new URL implementation
2026-06-27 23:56:47 +03:00
Halil DurakandKarl Seguin 0373b9ce3d Update src/browser/webapi/Node.zig
Co-authored-by: Karl Seguin <karlseguin@users.noreply.github.com>
2026-06-27 23:56:33 +03:00
Karl Seguin b054b26e56 dep: update libcurl and nghttp2
Nothing major, but the feature that caught my eye was the addition of a
threadpool for DNS resolution, rather than a thread-per-resolution (1). I've
enabled it.

(1) https://github.com/curl/curl/commit/39036c90216e059bbee64b86b198eae3135e0cda
2026-06-27 19:06:47 +08:00
Karl Seguin 0aaa77c7e6 minor: remove unused imports 2026-06-27 18:16:31 +08:00
Karl Seguin fb13ffc373 Merge pull request #2825 from lightpanda-io/replaceWith-DocumentFragment
webapi: replaceWith called with DocumentFragment should append its ch…
2026-06-27 12:08:24 +08:00
Karl Seguin 57b676459d Merge pull request #2824 from lightpanda-io/script_innerHTML
fix: Fix innerHTML parsing based on the target
2026-06-27 12:08:04 +08:00
Karl Seguin d18cb3ad79 Merge pull request #2823 from lightpanda-io/css_normalize_leading_zero
css: normalize fractions without leading 0
2026-06-27 12:07:50 +08:00
Karl Seguin f0e82f4d57 Merge pull request #2821 from lightpanda-io/sendBeacon
webapi, fake: Navigator.sendBeacon
2026-06-27 12:07:26 +08:00
Karl Seguin 7a59f24ee1 Merge pull request #2820 from lightpanda-io/select-add
webapi: Add Select.add
2026-06-27 12:06:53 +08:00
Karl Seguin b78170c71e fix: Reject xhr send() when send already active
This builds on top of 995efd57e6. That commit
tracked the number of requests being made on a single XHR instance (because a
new request can be initiated from a load/error callback of an existing one).
However, that was unbound. It wasn't just 1 old + 1 new, it was an unlimited
number of new requests, because we didn't prevent sending while sending was
already active.

This adds a boolean to track our send state, and prevents a send from happening
when a send is already active.
2026-06-27 09:05:26 +08:00
Boyd EbsworthyandClaude Opus 4.8 b94052dfa7 webapi: Fix cross-origin MessageEvent.source WindowProxy identity
MessageEvent.getSource returned the bare *Window, the only window accessor
that did not go through Window.Access.init. Every other accessor
(iframe.contentWindow, window.parent, window.top) wraps a cross-origin target
as *CrossOriginWindow. JS object identity is keyed by Zig pointer
(identity_map), so cross-origin event.source (the *Window) and
iframe.contentWindow (&window._cross_origin_wrapper) resolved to different JS
objects: `event.source === iframe.contentWindow` was false cross-origin while
true same-origin.

The WHATWG HTML spec requires these to be the same object regardless of origin
(one WindowProxy per browsing context; MessageEvent.source is that
WindowProxy). The mismatch breaks postMessage handshakes that authenticate the
sender by reference identity, e.g. keycloak-js's 3rd-party-cookie check
(`if (iframe.contentWindow !== event.source) return;`), which then times out
and fails OIDC init.

Route getSource through Window.Access.init(frame.window, source) — exactly like
IFrame.getContentWindow — so both paths resolve to the same per-frame proxy.
Same-origin behaviour is unchanged. Verified against Chrome 149 (identity holds
cross- and same-origin). Adds a regression test, cross_origin_message_source.html.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 18:10:25 +02:00
Karl Seguin 97cef1e900 Merge pull request #2822 from lightpanda-io/worker_requestAnimationFrame
fix: Crash on requestAnimationFrame from Worker
2026-06-26 22:53:52 +08:00
Boyd EbsworthyandClaude Opus 4.8 e6bd65626e cdp: Fix Page.frameAttached params double-wrapping that broke sub-frame interception
frameChildFrameCreated emitted Page.frameAttached with its payload wrapped
in an extra `.{ .params = ... }`. CDP.sendEvent already places the payload
into the event's `params` field, so this produced a malformed wire event
with double-nested params (`params.params.frameId`) — unlike every sibling
frame event in the same function, which passes its fields flat.

CDP clients (e.g. Playwright via connectOverCDP + page.route) parse
frameId/parentFrameId at the top level of params. With the fields one level
too deep the client never registers the child frame, so when that frame's
Fetch.requestPaused arrives it is bare-continued instead of matched against
a route. The result: request interception (page.route / Fetch) silently does
not apply to iframe (sub-frame) document navigations — the iframe loads from
the real network. The interception layer itself was never at fault; it does
emit requestPaused for sub-frames.

Drop the extra wrapper so the payload is flat. Add a regression test that
dispatches frame_child_frame_created and asserts Page.frameAttached carries
frameId/parentFrameId directly under params (fails on the double-nested shape).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 14:11:20 +02:00
Karl Seguin 700b4daf2e webapi: replaceWith called with DocumentFragment should append its children 2026-06-26 18:46:36 +08:00