Commit Graph
8802 Commits
Author SHA1 Message Date
Adrià Arrufat bbcc2f795d config: support embed mode in http nav delay and burst 2026-08-23 17:13:00 +02:00
Adrià Arrufat 3cf612d390 Merge branch 'main' into c-api 2026-08-23 10:20:01 +02:00
Karl Seguin 55fdb87946 Merge pull request #3249 from lightpanda-io/form-submission-files-and-charset
webapi: FormData encoding
2026-08-23 12:24:23 +08:00
Karl Seguin 318ba730b5 webapi: FormData encoding
FormData is now encoded based on the Page's encoding on form submission, or
UTF8 for a JS-created FormData. Newlines are also normalized as needed (sole
\r and \n become \r\n in most cases).

The value for a hidden _charset input is now set to the encoding of the FormData
(who knew this was a thing?).

Added a setter to File.input

findFramebyName ignores a disconnected frame.

Most of these were driven by the WPT /FileAPI/ category, but the changes impacts
a handful of cases throughout (e.g. various cases in /html/semantics/forms/ are
also improved).
2026-08-22 14:28:02 +08:00
Karl Seguin 23528f0cc4 Merge pull request #3246 from lightpanda-io/better-poll
chore: Remove Server component from Network
2026-08-22 11:15:11 +08:00
Karl Seguin 2d32e78838 chore: Remove Server component from Network
Network is less cohesive than https://github.com/lightpanda-io/browser/pull/3242
would indicate. It has two distinct and _completely_ separate responsibilities.

1 - It acts as the base for each HttpClient, providing a shared connection pool
    (for http and ws) and access to the process wide Cache, RobotStore,
    WebBothAuth, certificates, ...

2 - It accepts, polls and reads from CDP connection

There is zero relationship between these, and it's a particularly bad place for
this duality to exist because both parts are, in their own way, the main
multi-threaded junction in the system.

This commit is purely mechanical it:

1 - Keeps network as the base for each HttpClient.
2 - Extract the CDP interaction into the existing Server.zig
3 - Gives mcp's HttpServer its own accept loop
2026-08-22 10:11:30 +08:00
Karl Seguin 3e4b02a258 Merge pull request #3247 from lightpanda-io/canvas-png
add canvas toDataURL and toBlob returning 1x1 png
2026-08-22 10:01:43 +08:00
Karl Seguin 46d53792b8 chore: Network cleanup
Network has accumulated a bit of bagged. It knows a lot about certificates, it
knows a lot of the cache. I have plans to expand Network, and wanted to clean it
up.

1 - certificate logic moved to dedicated Certificates.zig
2 - Removed CurlDebugAllocator
    - this makes setup easier, to Updater can just init libcurl directly
3 - Change Updater to be a single function
4 - Cache initialization is don in the Cache
5 - ?Cache => Cache{.kind = .noop}
2026-08-22 09:21:18 +08:00
Karl Seguin a13c5fbc7b Apply same blank png logic to OffscreenCanvas
Move all of the blank png logic to OffscreenCanvas and apply it to the existing
convertToBlob. I agree it doesn't really make that much sense here, but Canvas
already references OffscreenCanvas, so given its current usage, it's the most
ergonomic place to put it.

Canvas's ToBlobCallback now runs microtask after executing the callback and
lazily creates the Blob for simpler blob lifecycle.
2026-08-22 09:14:41 +08:00
Karl Seguin e01baa1139 Merge pull request #3242 from lightpanda-io/network-cleanup
chore: Network cleanup
2026-08-22 08:21:27 +08:00
Karl Seguin 1b305cdec0 Merge pull request #3225 from lightpanda-io/agent-exa
browser: add exa search engine support
2026-08-22 07:06:27 +08:00
Karl Seguin 57bcdfed10 chore: Simplify Network and HttpClient init
Remove app field from Network
2026-08-22 07:05:05 +08:00
Karl Seguin decedca6e7 chore: Network cleanup
Network has accumulated a bit of bagged. It knows a lot about certificates, it
knows a lot of the cache. I have plans to expand Network, and wanted to clean it
up.

1 - certificate logic moved to dedicated Certificates.zig
2 - Removed CurlDebugAllocator
    - this makes setup easier, to Updater can just init libcurl directly
3 - Change Updater to be a single function
4 - Cache initialization is don in the Cache
5 - ?Cache => Cache{.kind = .noop}
2026-08-22 07:04:58 +08:00
Karl Seguin 9f4b39d723 Merge pull request #3239 from lightpanda-io/ratelimiter
http: Add optional rate limit
2026-08-22 06:58:52 +08:00
Pierre Tachoire 342eaf1036 add canvas toDataURL and toBlob returning 1x1 png 2026-08-21 19:53:42 +02:00
Pierre Tachoire d6d6248f34 Merge pull request #3244 from lightpanda-io/media-query-device
add device-width / device-height media features
2026-08-21 17:34:05 +02:00
Pierre Tachoire bc5289778a add device-width / device-height media features
matchMedia("(min-device-width: …)") always returned false, so scripts
scanning for the first matching bound never terminated.

device-* resolves against the viewport, like window.screen.width/height.
2026-08-21 16:07:23 +02:00
Pierre Tachoire f70c16ffb2 Merge pull request #3243 from lightpanda-io/nikneym/geolocation-ordering
`Geolocation`: order `PositionOptions` fields lexicographically
2026-08-21 14:41:16 +02:00
Halil Durak cfe885c319 Geolocation: order PositionOptions fields lexicographically 2026-08-21 15:17:03 +03:00
Karl Seguin be101e188c Merge pull request #3238 from lightpanda-io/fileapi-blob-spec
webapi: Blob / File conformance
2026-08-21 18:49:05 +08:00
Karl Seguin 467e372fd8 Merge pull request #3237 from lightpanda-io/domparser-realm
webapi: DOMParser capture owning frame for correct URL
2026-08-21 18:48:32 +08:00
Karl Seguin c80b3f1e03 Merge pull request #3241 from lightpanda-io/arena_leak
mem: Cleanup arena leak on page shutdown with live animations
2026-08-21 18:25:40 +08:00
Karl Seguin accb34eaa4 Merge pull request #3233 from rohitsux/feat/geolocation-emulation
feat: navigator.geolocation + Emulation.setGeolocationOverride
2026-08-21 14:47:38 +08:00
Karl Seguin ede211e5a0 WebApi: Improve Geolocation API
Add missing toJSON, use Arena + Finalizers for delivery / GeolocationPosition
and coordinates. Return permission denied if permission isn't set, regardless of
override. Split structs into their own files.
2026-08-21 11:24:01 +08:00
Karl Seguin 1adc8a3b70 mem: Cleanup arena leak on page shutdown with live animations 2026-08-21 09:30:28 +08:00
Karl Seguin 4a001f932c Merge pull request #3229 from lightpanda-io/element-left-position
webapi: improve "rendering" of an element's left position
2026-08-21 07:31:11 +08:00
Karl Seguin 038257dfd7 Merge pull request #3235 from lightpanda-io/cargo-non-error-progress
chore: don't let cargo's build progress show up as a "failed command"
2026-08-21 07:30:54 +08:00
Karl Seguin 09edfd3ce5 http: Add optional rate limit
Add an optional per-host rate limit. This currently only applies to the top-
level navigation. This makes it simpler to implement and simpler to reason
about. The full load of a page is only ever delayed at its head, not
sporadically through the page loading.

The use-case where a RateLimiter is most useful is when the browser is crawling
multiple pages of the same site, and in that case, the top-level rate limit
still applies some degree of limit to any linked resources (e.g. a JS on a
different host).

`--http-nav-delay` is the delay, in milliseconds, to apply to top level
navigates per host. Currently defaults to 0 (disabled).

`--http-nav-burst` is the burst allowed per host. Defaults to 1 (has no impact
when `--http-nav-delay` is disabled).
2026-08-20 16:03:42 +08:00
Karl Seguin b70f7a325e webapi: Blob / File conformance
1-
Per spec, dictionary objects should be loaded in lexicographical order (a). So
the following always pushes `endings` before `type`

```js
  new Blob([], {
    get type()    { order.push('type'); return ''; },
    get endings() { order.push('endings'); return 'transparent'; },
  });
```

This requirement is now enforced by a comptime check. So, a lot of files were
updated to satisfy this requirement.

2-
Blob parts now work with the @@iterator protocol. This is done more generically
(via `value.iterator())` but is currently only used by Blob (and File). Other
types that need this (e.g. URLSearchParams) can be done in a follow up.

3-
Add support for Blob.textStream

4-
Reject XHR/Fetch requests on blob URLs if the method isn't GET

5-
Strip #hash from blob URL when doing lookup

All of this fixes ~175 FileAPI WPT cases, though it's possible #1 (the
dictionary ordering) helps with a few others.

(a) https://webidl.spec.whatwg.org/#js-dictionary
2026-08-20 13:57:51 +08:00
Karl Seguin 28c5778fde webapi: DOMParser capture owning frame for correct URL
The URL assigned to a document parsed via DOMParser should come from the Frame
which created the DOMParser.
2026-08-20 12:39:16 +08:00
Karl Seguin 52623fe7ef chore: don't let cargo's build progress show up as a "failed command"
Cargo prints its progress to stderr. Zig's build sees the stderr content and
prints it as a "failed command: ...". Capture cargo's stderr to silence this
fake-error. A status != 0 still causes the error to be printed.
2026-08-20 09:59:24 +08:00
Rohit 3901858977 fix(cdp): advertise geolocation override methods in protocol + test denied path 2026-08-19 20:50:05 +05:30
Rohit a67bfbb74d feat(webapi): resolve navigator.geolocation from the emulation override 2026-08-19 20:33:02 +05:30
Rohit 0e875e2b03 feat(webapi): add navigator.geolocation with async error delivery
Adds the Geolocation and GeolocationPositionError interfaces plus a
navigator.geolocation accessor. getCurrentPosition schedules delivery
on the frame's js.Scheduler so callbacks always fire off the calling
stack, and covers the no-override path where no
Browser.geolocation_override is set: the error callback receives a
GeolocationPositionError with code POSITION_UNAVAILABLE (2), or
PERMISSION_DENIED (1) if the geolocation permission was denied via
CDP. Reading an override into a successful GeolocationPosition and
watchPosition/clearWatch are left for later work.
2026-08-19 20:16:21 +05:30
Adrià Arrufat 9a57a34b46 tools: cap exa search highlights to 3 sentences 2026-08-19 16:42:43 +02:00
Rohit 56ef7b95ee feat(cdp): store Emulation.setGeolocationOverride on the browser 2026-08-19 19:53:16 +05:30
Karl Seguin d40f68ba56 webapi: improve "rendering" of an element's left position
1. The horizontal position of an element is now calculated based on the
horizontal position of it's siblings (up the tree). Rather than merely the
count * default width.

2. translateX is parsed on inline styles and applies to the horizontal position

1 & 2 fix the https://lseo.com/ issue, but they add overhead to APIs that can be
used a lot. So:

3. Most element dimensions api relied on getElementDimensions which calculated
   both the height and width dimensions, even though they only needed once
   (e.g. getClientHeight only needs the height). These methods now only get
   the axis that they care about

4. Because we do more style sheet lookups, and thus more lookups in
   Frame._element_styles, Element.flags now has an has_inline_style which
   helps avoid the lookup.
2026-08-19 18:28:28 +08:00
Karl Seguin 46de01944e Merge pull request #3228 from lightpanda-io/js-promise-reject-bad-receiver
webapi: promise-returning operations reject, don't throw, on bad receiver
2026-08-19 15:38:14 +08:00
Karl Seguin 6f53c42df9 Merge pull request #3227 from lightpanda-io/xml-parse-fidelity
webapi: xml parsing reject documetns that are not well formed
2026-08-19 15:38:03 +08:00
Karl Seguin 9c609d056d Merge pull request #3218 from pasmud/gaz/lightpanda-io-browser-aboutblank-global
fix: replace bootstrap about:blank global on first navigation (#3215)
2026-08-19 13:24:30 +08:00
Karl Seguin 5f96fc1c3c Add condition to full page reload on about:blank from CDP
The unconditional full load incurs a performance hit in the common case where
the about:blank is safe to use. This commit restores the fast-path only when
(a) the page is waiting for its initial navigate (same as before) and (b)
no Runtime.* methods were executed (i.e. no driver-driven JS was executed on
about:blank)
2026-08-19 12:48:21 +08:00
Karl Seguin 289620fbf8 webapi: promise-returning operations reject, don't throw, on bad receiver
We currently implement a v8 signature check on the receiver. This throws on
failure. However, for a promise-returning function, it should reject the
promise instead. This skips the (v8) signature check for promise-returning so
that it flows through the normal code which does rejection.

Fixes a few WPT cases (in fetch and FileAPI, but probably others too).

This reject, don't throw, is an ongoing thing that we're fixing, e.g.
https://github.com/lightpanda-io/browser/pull/3095
2026-08-19 12:00:14 +08:00
Karl Seguin 6acfc03579 Merge pull request #3226 from navidemad/agents-md-download-v8
AGENTS.md: mention make download-v8 before building
2026-08-19 08:55:41 +08:00
Karl Seguin 25aa46a6ca webapi: xml parsing reject documetns that are not well formed
Hooks into the xml5ever parse_error callback to capture parse errors and reject
malformed XML. Because of this stricter error handling, we need to do some
input pre-processing for edge cases (thank you WPT). We need to strip out
<!DOCTYPE svg [ <!ENTITY ...> ]> which comes form Illustrator SVG export since
that now causes errors (but should be ignored).

Finally, by default xml5ever closes any opened tags at the end of the stream.
Per WPT, these should be invalid.

The rust work was all Claude-driven.
2026-08-19 08:52:15 +08:00
Karl Seguin 1ed8d4a35d trim comments 2026-08-19 08:25:57 +08:00
Karl Seguin f2b4043171 Merge pull request #3222 from lightpanda-io/style-attr-resync
webapi: Re-parse element.style when style attribute changes
2026-08-19 07:45:36 +08:00
Karl Seguin 4b06c248e7 use element.ownerFrame to access StyleManager 2026-08-19 07:33:38 +08:00
Karl Seguin 20293bca9d Merge pull request #3220 from lightpanda-io/fileapi-filereader-async
webapi: make FileReader asynchronously + proper text decoding
2026-08-19 06:55:13 +08:00
Karl Seguin 411eed0a80 Merge pull request #3224 from lightpanda-io/cd-obey-robots
cdp: add obeyRobots to LP.configureCDP
2026-08-19 06:54:49 +08:00
Navid EMAD 2aecdab322 AGENTS.md: point agents at make download-v8 before building 2026-08-18 22:56:16 +02:00