Commit Graph
8835 Commits
Author SHA1 Message Date
Adrià Arrufat 4583066b2f tools: drop the 'no rendering' claim from the driver guidance
The engine renders PNGs since #3231. What is still true for the model is
that no tool exposes pixels, so say that instead.
2026-08-25 15:24:01 +02:00
Halil Durak 08219f91d6 Merge pull request #3230 from lightpanda-io/nikneym/mimic-image-fetch
Introduce `--load-resources`, supporting `image` parameter
2026-08-25 14:41:21 +03:00
Halil Durak ef7dc313e6 update tests 2026-08-25 14:20:39 +03:00
Halil Durak eb9080be16 Session: update stale comment 2026-08-25 14:20:39 +03:00
Halil Durak f07f818d2f Image: fix generation update order 2026-08-25 14:20:39 +03:00
Halil Durak 87a87ba62e HttpClient: remove pending_low_queue, separate keys for headers_only in cache, more eager connection reuse 2026-08-25 14:20:38 +03:00
Halil Durak 3265d66052 change how --load-resources are provided from CLI 2026-08-25 14:18:47 +03:00
Halil Durak 9b9ecedc7d Image: cover src changes on attributeRemove 2026-08-25 14:18:47 +03:00
Halil Durak 4c946fd172 pendingLoadCompleted can reach documentIsComplete
which results in running events on a destroyed object.
2026-08-25 14:18:47 +03:00
Halil Durak add0f1729f move loadImage and ImageLoad to resource_load.zig 2026-08-25 14:18:47 +03:00
Halil Durak 46f230a44d remove unnecessary import 2026-08-25 14:18:47 +03:00
Halil Durak 2a1659b967 Frame: remove unreachable in dataCallback of ImageLoad 2026-08-25 14:18:46 +03:00
Halil Durak c1079444c4 addHeader -> setHeader + enable low prio for images 2026-08-25 14:18:46 +03:00
Halil Durak d254302f6d update tests 2026-08-25 14:18:46 +03:00
Halil Durak 24019ef1a7 testing interface should respect --load-resources 2026-08-25 14:18:46 +03:00
Halil Durak 6f7aa67c21 update help.zon 2026-08-25 14:18:45 +03:00
Halil Durak e58f99da18 add --load-resources CLI arg, supporting image param 2026-08-25 14:18:45 +03:00
Karl Seguin feb8d17863 Merge pull request #3260 from staylor/fix/termination-async-module-reentry
stability: drop async module completions after termination
2026-08-25 18:49:26 +08:00
Karl Seguin b7f1a2d6cd check terminatePending on Frame.isGoingAway 2026-08-25 18:38:05 +08:00
Karl Seguin 289502e19a Merge pull request #3231 from lightpanda-io/screenshot
Screenshot
2026-08-25 18:12:00 +08:00
Karl Seguin 0c24db4a00 mem: try lto=thin
Try lto=thin in rust so that the html5ever code sits together and triggers less
misses which result in more memory being used.
2026-08-25 17:02:56 +08:00
Karl Seguin de422a72f5 Embed DejaVuSansMono-Bold.ttf for bold headings
fix slant direction for italics
2026-08-25 16:02:51 +08:00
Adrià Arrufat dbe89c1b31 Merge pull request #3252 from keenableai/feat/keenable-search-engine
search: add Keenable engine with a keyless rung above the DDG scrape
2026-08-25 08:53:24 +02:00
Ilya Bogin 887e4108bb Merge pull request #1 from lightpanda-io/keenable-review-followups
search: repin zenai to the merged commit and finish the review follow-ups
2026-08-25 09:01:39 +03:00
Karl Seguin 341a015708 Merge pull request #3259 from navidemad/fix-mouseevent-coordinate-flooring
webapi: floor MouseEvent coordinate getters to integers, Chrome-style
2026-08-25 09:32:04 +08:00
Karl Seguin 5d4b01e3a7 add flooring to click-like pointer events 2026-08-25 08:36:32 +08:00
Karl Seguin b403c51ea1 Merge pull request #3257 from navidemad/fix-b20-draggable-idl
webapi: implement the HTMLElement.draggable IDL attribute
2026-08-25 08:17:13 +08:00
Karl Seguin b72042365a Merge pull request #3254 from lightpanda-io/wpt-webdriver-click-semantics
webdriver: better mouse events
2026-08-25 07:09:55 +08:00
Karl Seguin 4d19bf1e5a Merge pull request #3253 from lightpanda-io/URLSearchParams
webapi: URLSearchParams improvements
2026-08-25 07:09:14 +08:00
Karl Seguin 99ee50259b Merge pull request #3248 from lightpanda-io/transfer-single-outcome-guarantee
http: Guarantee Transfer contract of single outcome callback
2026-08-25 07:08:54 +08:00
Karl Seguin 174ba384b8 Merge pull request #3261 from lightpanda-io/mcp-log-format-default
mcp: make logfmt a Config default instead of an override
2026-08-25 07:07:45 +08:00
Adrià Arrufat e02c45888d mcp: make logfmt a Config default instead of an override
MCP mode unconditionally set log.opts.format = .logfmt after the
--log_format flag had already been applied, so `--log_format pretty`
was silently ignored. It also ran after the "starting server" line,
which came out in the pre-override format in debug builds.

Move it into Config.logFormat() as a mode-aware default, mirroring
what logLevel() does for agent mode: null -> logfmt for mcp, and an
explicit flag wins.
2026-08-24 19:35:07 +02:00
Scott Taylor 8673f0815e stability: drop async module completions after termination
Assisted-By: devx/c74ae588-eb01-43ac-9c5d-2e6938841883
2026-08-24 12:32:26 -04:00
Navid EMAD 110d0076a4 webapi: floor MouseEvent coordinate getters to integers, Chrome-style
clientX/clientY, screenX/screenY, pageX/pageY, layerX/layerY and the x/y
aliases returned the MouseEventInit double verbatim, so a synthetic event
built with clientX: 47.5 read back 47.5. Chrome floors these getters on
MouseEvent and its non-pointer subclasses (DragEvent, WheelEvent) and
exposes fractional coordinates on PointerEvent only; page code and
automation tooling written against Chrome assume integer mouse
coordinates. The getters now floor unless the event's _type tag says
pointer_event, so the inherited PointerEvent accessors keep the
fractional double.

Closes #3258
2026-08-24 16:47:47 +02:00
Navid EMAD 763ffcee41 webapi: implement the HTMLElement.draggable IDL attribute
Reading el.draggable returned undefined for every element, and assigning
it created a plain JS own property with no reflection onto the content
attribute. Implement the reflected property per the HTML spec: the
"true"/"false" keywords are matched ASCII case-insensitively, the auto
state defaults to true for <img> and for <a> with an href (matching
Chrome), and the setter writes the literal "true"/"false" onto the
content attribute.

Closes #3255
2026-08-24 15:37:01 +02:00
Karl Seguin 08d581c61e webdriver: better mouse events
Depends on https://github.com/lightpanda-io/wpt/pull/77

Track click count so that we can correctly fire a double click. On click, if
the mousedown and mouseup targets differe, find the nearest common inclusive
ancestor. Our `dispatchMouse` now sets the correct buttons value.

Also, HTMLElement.click() should be a PointerEvent (not a MouseEvent)

Improves various /uievents/ WPT cases.
2026-08-24 20:57:09 +08:00
Adrià Arrufat 12ecf27fb1 search: make SearchEngine declaration order the .auto preference order
Mirror the zenai provider pattern: the enum's declaration order is the
single source of truth for the .auto cascade, asserted at comptime against
api_engines (auto first, one table entry per API engine in tag order,
duckduckgo last with no entry). The enum reorders brave before tavily to
match the table's actual preference — persisted settings are unaffected
(ZON stores tag names).

Each table entry now carries a .keyless field; the hardcoded keenable
keyless rung, searchEngineKeyless, and searchExplicit's comptime gate all
derive from it, engineIndex collapses to arithmetic, and apiSearch takes a
typed ?[]const u8 key instead of anytype.
2026-08-24 13:01:31 +02:00
Adrià Arrufat f1742ad1af search: repin zenai to the merged commit and finish the review follow-ups
- build.zig.zon points at lightpanda-io/zenai's merge commit of zenai#9
  (same tree, so the hash is unchanged)
- the keyless rung is no longer skipped when KEENABLE_API_KEY is set:
  the public endpoint has its own rate-limit regime, so it is worth
  trying after a failed keyed attempt — which the search tool
  description already promised
- keenable retries are disabled: the fallback cascade is the retry
  mechanism, and honoring the public endpoint's 60s Retry-After would
  stall the search tool short of the DDG rung
- stale SearchEngine/searchExplicit doc comments updated for keyless
2026-08-24 10:39:47 +02:00
Karl Seguin e06d523da8 webapi: URLSearchParams improvements
`has` add support for optional value (matches name AND value)

`delete` preserve entry order

`sort` compares by UTF-16

`forEach` iterates by index since the callback can mutate the list

Minor improvement to a handful of WPT tests, e.g.
/url/urlsearchparams-delete.any.html  (first of a handful of /url/ WPT
improvements)
2026-08-24 16:14:43 +08:00
Ilya Bogin 56e5daed54 search: track zenai review changes for the keenable engine
zenai's review round made keyless explicit in the client's type
(init takes ?[]const u8; null selects the public endpoint) and removed
the always-empty description field from results:

- the .auto keyless rung and searchExplicit pass null instead of "";
  the null-key call is comptime-gated to keyless-capable engines and
  apiSearch's key parameter is anytype to admit both shapes
- a set-but-empty KEENABLE_API_KEY is now keyed and fails loudly
  instead of silently switching to the keyless rate-limit regime
- formatKeenableMarkdown reads snippet only (description no longer
  exists to fall back to)
- build.zig.zon repinned to the reviewed zenai commit
2026-08-24 10:44:38 +03:00
Karl Seguin 910395c764 Merge pull request #3250 from lightpanda-io/silence-write-failed-test-http-error
chore: Silence the sporadic WriteFailed HTTP Error from the test server
2026-08-24 11:51:01 +08:00
Ilya Bogin 6cbe30b088 search: add Keenable engine with a keyless rung above the DDG scrape
Adds keenable to the search tool's engines (KEENABLE_API_KEY, tried
after brave/tavily/exa in .auto). Unlike the other engines it also
answers without any key: its client routes an empty key to the public
endpoint (rate-limited per client IP), so .auto now tries that as the
last rung before the DuckDuckGo scrape, and an explicit
/searchEngine keenable works keyless instead of erroring. Engine table
entries gain init_options so the Keenable client can carry the
lightpanda attribution header.

Needs the zenai Keenable search client (lightpanda-io/zenai PR #9); the
zon pin points at that branch until it lands.
2026-08-23 15:42:06 +03:00
Karl Seguin 4b3c5ed947 chore: Silence the sporadic WriteFailed HTTP Error from the test server
No clue why this happens, but if the error mattered, a test would fail. A lot
of tests can be "harsh" on the server (e.g. a frame that navigates its parent
away while some resource load), so a WriteFailed error isn't exactly surprising
2026-08-23 13:37:08 +08: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 a6618fff63 http: Guarantee Transfer contract of single outcome callback
HttpClient guarantees that only one of done/error/shtudown callback will be
called. But that guarantee had a hole when a done/error callback would trigger
JS that caused an HttpClient.abort (e.g. by scheduling a navigation).

So far, this isn't a problem. fetch/XHR guard against this themselves, and
ScriptManager doesn't care of it happens.

But https://github.com/lightpanda-io/browser/pull/3230 doesn't guard against it
and would crash if it happens: its doneCallback frees `self` but can re-enter
shutdown which needs `self`. While 3230 could fix this issue, I'd prefer to
bake this contract into the HttpClient. Transfers now have an
`_outcome_delivered: bool` which guarantees that only one of done/error/shutdown
is called.
2026-08-22 11:09:52 +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