Commit graph

508 commits

Author SHA1 Message Date
Shannon Booth
ef6753a9f9 LibWeb+LibTextCodec: Wire decoder options through TextDecoder
Add explicit IgnoreBOM and ErrorMode options to LibTextCodec decoders,
and thread them through TextDecoder and TextDecoderStream.

This lets Web-facing decoder APIs preserve BOMs when requested and use
fatal error handling without post-processing decoded output.

NB: RemoveBOM was renamed to IgnoreBOM as "RemoveBOM" is the name
used by encoding_rs and was previously an implementation detail.
The new name matches what is used by the encoding standard as it
is now also used in LibWeb.
2026-06-23 07:25:11 +02:00
Andreas Kling
b91ff9ebfd UI/Qt: Keep macOS app alive without windows
Disable Qt quit-on-last-window behavior on macOS and install an
application-level menu so useful commands remain available after the
last browser window closes.

Reuse shared application actions and menus for Settings, Bookmarks,
History, Help, and global appearance controls. Centralize window-aware
commands such as New Tab, New Window, Open File, Open Location, and
Reopen Recently Closed so the browser window and windowless app menu
use the same behavior. Keep the location editor focused for new blank
windows after the native window has been activated.
2026-06-22 01:13:53 +02:00
Andreas Kling
202159be18 UI: Share macOS web selection color
Move the active macOS web selection color into LibWebView so AppKit
and Qt use the same value when building the WebContent system palette.
Qt now also asks AppKit for inactive selection colors on macOS, matching
the AppKit frontend while leaving other Qt platforms on QPalette.
2026-06-22 01:13:53 +02:00
Sam Atkins
fdfe806e68 LibDevTools+LibWeb: Let DevTools remove IndexedDB data
Firefox exposes removal operations for IndexedDB databases, object
stores, and records from the Storage panel. Route those actor requests
to LibWeb so DevTools can delete the selected data and receive the
update or clear event needed to refresh the panel.
2026-06-19 14:25:39 +02:00
Sam Atkins
e667aaaab1 LibDevTools+LibWeb: Send IndexedDB change updates
The Storage panel expects storesUpdate messages after watched storage
changes. Summarize committed IndexedDB mutation logs into DevTools paths
and forward them through WebContent so Firefox can refresh database,
object-store, and record rows without polling.

Firefox's behaviour is less than ideal here. A lot of things don't
update automatically even inspecting a page in Firefox. Some
things (like new databases) won't show up until you fully refresh the
page. So that makes it a bit hard to know that we're doing things
correctly. As far as I can tell, we are at least behaving as well as
Firefox requires.

We do have one workaround: Firefox doesn't display record updates
without a manual refresh, and in fact any change messages for them show
up as rows in the host's database table. So for now, we filter them out
to avoid visual weirdness in the inspector.
2026-06-19 14:25:39 +02:00
Sam Atkins
cb47dbfc7a LibDevTools+LibWeb: Show IndexedDB in DevTools
Firefox asks the storage watcher for an indexed-db resource before it
shows IndexedDB entries in the Storage panel. Add an IndexedDB actor and
serialize the live LibWeb database registry on demand, so WebContent can
return the host tree and table rows without duplicating database state.

Use the LibWeb inspection helpers to read IndexedDB internals, and keep
the Firefox protocol shape in LibDevTools. WebContent only forwards the
serialized response over the existing DevTools IPC path.
2026-06-19 14:25:39 +02:00
Luke Wilde
8dc8835b64 LibWeb+LibWebView+WebContent: Allow muted media to autoplay by default
The autoplay setting was binary and its default blocked all media,
including muted video, leaving sites that rely on muted autoplay
visibly broken. Replace it with a tri-state user-agent autoplay
policy (allow audio and video, block audio, or block audio and video)
defaulting to allowing only inaudible media to autoplay.

This is enforced through the media element's "allowed to play" check,
so unmuting a muted autoplay or calling `play()` cannot slip audio
past the policy; audible playback is permitted once the document has
been activated by the user. The policy lives in a dedicated
AutoplaySettings consulted from HTMLMediaElement instead of the
Permissions Policy "allowed to use feature" check it was previously
conflated with.
2026-06-19 09:41:32 +02:00
Sam Atkins
147d4595c6 LibWebView: Restore RFC cookie storage behavior
In 11b053b154 I accidentally changed the
behaviour of CookieJar::set_cookie() to not match what the RFC
requires, particularly when dealing with too-long paths. This commit
restores the original behaviour, now that the validation required by
DevTools happens elsewhere, before set_cookie() is called.
2026-06-18 11:37:36 +02:00
Sam Atkins
b1547d467e LibHTTP+LibWebView: Share Cookie conversion
Nothing about `parsed_cookie_from_devtools_cookie()` is specific to
DevTools, so move it to ParsedCookie.h as `parse_cookie()` instead.
2026-06-18 11:37:36 +02:00
Aliaksandr Kalenik
40d446d558 LibWebView+WebContent: Stop creating GPU Skia backend in WebContent
Canvas and display list rasterization now run in the Compositor
process, so WebContent no longer needs its own Skia GPU backend. Drop
the WebContent --force-cpu-painting option and stop forwarding it when
launching the renderer. The flag remains available for Compositor.
2026-06-18 10:25:44 +02:00
Aliaksandr Kalenik
1b5bdb2b41 LibWeb+LibWebView+WebWorker: Initialize transport peer pid on Windows
WebWorker control connections can transfer handles from the browser
process to the worker process, including RequestServer and ImageDecoder
transport handles sent during worker startup. On Windows, serializing
those attachments needs the destination process id so DuplicateHandle
and WSADuplicateSocketW can target the peer process. WebWorker was
excluded from the generic helper-process InitTransport handshake,
leaving the transport without a peer pid before any attachment-bearing
message was sent.

Add InitTransport to the WebWorker server endpoint, implement the
server-side peer pid exchange, expose the message type through
WebWorkerClient, and let the shared helper launcher perform the
handshake for workers as it does for other Windows IPC clients.
2026-06-18 04:06:30 +02:00
Tim Ledbetter
0db82b3133 LibWebView+UI/Qt: Reuse an existing history tab when viewing history
Previously, the "View History" action always opened a new tab. We now
switch to an existing `about:history` tab when one exists in the active
window and fall back to opening a new tab otherwise.
2026-06-17 12:31:07 +02:00
sideshowbarker
766bc991ed LibWebView: Make the session-history-mirror merge linear
Problem: While a document was concurrently loaded, a burst of sync same-
document history navigations (e.g. a pushState flood) could spin the UI
process at full CPU — and on slow/Sanitizer builds, intermittently time
out other tests (since one WebContent process is reused across tests).

Cause: The UI process keeps an authoritative session-history mirror, and
merges each WebContent snapshot into it. find_merge_anchor compares each
local entry against each incoming one. Every URL comparison serializes
both URLs. When a snapshot briefly diverges from the mirror, the anchor
is no longer near the end. So, the search degraded to a deep quadratic
walk — with a string serialization per-comparison. A flood compounded
that from both ends: Every pushState added a top-level entry — driving
the count each walk must cover into the hundreds — and also triggered a
history update. So, the merge ran again for every one of them.

Fix: Index the incoming entries by serialized URL once — keyed as URL
equality compares (full serialization, fragment included). So, the URL-
keyed anchor searches are linear, not quadratic.
2026-06-17 12:25:53 +02:00
Andreas Kling
a9b9cdbec1 LibWebView: Make helper sandboxing opt-out
Apply helper process sandboxing by default and replace the old
--enable-sandbox switch with --disable-sandbox. Propagate the opt-out
from Ladybird, test-web, and WebDriver to WebContent, WebWorker,
RequestServer, ImageDecoder, and Compositor.
2026-06-16 19:02:54 +02:00
Andreas Kling
19168446c6 UI/Qt: Add navigation history menus
Show native history menus when users right-click or long-press
the back and forward toolbar buttons. Populate entries from the
UI-process session history mirror, using saved history titles and
favicons when available and falling back to the URL and globe icon
otherwise.

Share the Qt base64 PNG icon helper so bookmark menus and navigation
history menus render stored favicons consistently.
2026-06-16 16:34:33 +02:00
Andreas Kling
bbeb2eb69c LibWebView: Keep UI history authoritative during races
Keep UI process session history authoritative across overlapping
fallback loads and traversals. WebContent can finish a superseded
history load with a live document matching the UI seed URL while its
local step, document state id, and Navigation API keys still describe
a temporary partial list.

Reconstruct the current entry around the UI-owned list in that case.
This avoids making the UI process adopt WebContent's incomplete
snapshot.

Track UI-started fallback loads by URL so unrelated navigations cannot
consume the pending seed state. Resolve deferred WebDriver completions
through the view registry so callbacks queued before a process swap do
not touch a destroyed view.

Add WebDriver coverage that waits for explicit UI/WebContent history
convergence after the relevant document events. The waits poll
observable history state instead of depending on timing.
2026-06-16 14:55:22 +02:00
Shannon Booth
6719f01a40 LibHTTP: Treat PSL star-rule domains as public suffixes
Use IncludeStarRule::Yes for cookie public-suffix checks so domains not
explicitly listed in the PSL still get treated as public suffixes via
the implicit * rule. This fixes accepting cookies for bare TLD-like
domains.
2026-06-16 06:14:07 +02:00
Shannon Booth
3f7b31fc78 LibURL: Let Host use PublicSuffixData star rule matching
Ever since PublicSuffixData was created, it was using "no star rule"
matching, which is what is needed for the address bar to distinguish
between a domain and a search. URL::Host on the other hand requires
the fallback star rule. Which rule is needed depends on the use case
of the PSL. Support both use cases by a flag in PublicSuffixData.
2026-06-16 06:14:07 +02:00
Andreas Kling
a11c281dc3 Compositor: Handle pinch zoom asynchronously
Apply pinch zoom deltas to the compositor's visual viewport transform
so the currently presented display list can respond without waiting for
the WebContent main thread. Keep the normal WebContent pinch event path
so the real VisualViewport state and DOM-visible events catch up after.

Only take the compositor path when async scrolling is enabled and there
are no blocking wheel listeners, since pinch zoom dispatches a synthetic
wheel event that script may cancel. Coalesce queued pinch events in
WebContent so main-thread catch-up can adopt multiple gesture deltas
together.

Use the compositor visual viewport transform for wheel hit testing and
consume wheel deltas as visual viewport pan while zoomed. Scale the
handoff to layout viewport scrolling by the inverse visual viewport
scale, so touchpad momentum does not jump when the visual viewport hits
an edge.
2026-06-16 02:03:59 +02:00
Andreas Kling
b06955277a LibWeb: Stabilize same-document history mirrors
Same-document navigations now commit synchronously in WebContent, while
the UI process mirror learns about them over asynchronous IPC. A stale
UI seed could be accepted back into a live non-initial document and
overwrite its latest entry, making queued traversals target unreachable
entries.

Share descriptor comparison helpers between LibWeb and LibWebView.
Reject stale top-level seeds against the active document latest entry,
and let the UI process adopt WebContent current snapshots when a seed is
rejected. Test-only session history dumps now first send WebContent
current state synchronously, so dumps observe the converged state.

Allow post-load UI seeds to carry UI-owned nested histories that the
freshly loaded top-level document has not reconstructed yet. Add unit
coverage for matching those seeds while still checking top-level state.
2026-06-16 00:00:38 +02:00
Andreas Kling
67030ceead LibWebView: Complete WebDriver same-document traversals
Complete pending WebDriver navigation waits when WebContent confirms
that a same-document history traversal step was applied. These
traversals do not always produce a load event, and waiting only for a
later session history snapshot could let the WebDriver command return
before the UI had observed the applied step.

This keeps the WebDriver session history test from racing into later
commands while a previous same-document traversal is still settling.
2026-06-14 17:38:44 +02:00
Andreas Kling
24f37c6732 LibWebView: Keep browser history in the UI process
Use the LibWebView history mirror to preserve traversable session
history across WebContent process swaps. WebContent reports snapshots to
the UI process, and new renderers can be seeded from the mirror.

Browser back and forward now resolve through the UI-owned used history
steps. WebContent still runs the spec traversal path when the current
renderer has enough matching state to do so.

Handle canceled and no-op UI navigations without leaving speculative
history entries or pending WebDriver waits behind. Preserve traversal
precheck state across synchronous IPC shutdown, and avoid overwriting a
restored target entry's persisted scroll state before the document has
adopted that entry.
2026-06-14 17:38:44 +02:00
Andreas Kling
78bb7b8d45 LibWebView: Add a UI session history model
Add a browser-side model for top-level history entries and history step
coordinates. This gives the UI process a structure to mirror WebContent
history across process swaps.

Add debug dumping support alongside the model so traversal state can be
inspected while working on back and forward behavior.
2026-06-14 17:38:44 +02:00
Shannon Booth
790b9bd36a LibWebView: Add async cookie deletion internals
Add Internals.deleteAllCookies(), backed by an async WebContent to
browser request and ack pair. CookieJar can now clear transient and
persisted cookies. Note that we only delete all cookies associated
with the current URL so that tests are able to run in parallel with
one another without impacting shared cookie state.
2026-06-13 10:18:33 +02:00
Sam Atkins
0b9e59f61f LibDevTools: Allow editing Web Storage
Firefox sends the same storage actor mutation requests for Web Storage
that it uses for cookies. Handle addItem, editItem, removeItem, and
removeAll for localStorage and sessionStorage actors.

Apply the changes through the browser-process storage jar and emit the
matching store update packets so the Storage panel stays current after a
DevTools-initiated edit.
2026-06-11 16:08:33 +01:00
Sam Atkins
a75e9f23db LibWeb+LibDevTools: Report Web Storage changes
Firefox keeps the Storage panel current by sending store update packets
when localStorage or sessionStorage changes. Forward successful Web
Storage mutations to the storage actors and emit the matching update or
clear packet.

Use listener IDs for storage updates so the local and session storage
actors can subscribe independently.
2026-06-11 16:08:33 +01:00
Sam Atkins
ddb4bdadd7 LibDevTools: Populate DevTools Web Storage
Firefox exposes localStorage and sessionStorage through the same
storage actor protocol used by cookies. Add matching resources for the
current tab so the Storage panel can list key/value pairs.

Read the values through WebContent rather than directly from the
browser process. Session storage lives in LibWeb, and using the same
path for both stores keeps the actor independent of the backing store.
2026-06-11 16:08:33 +01:00
Sam Atkins
9e4cd527aa WebContent+LibWebView: Add dumping for session storage 2026-06-11 16:08:33 +01:00
Sam Atkins
11b053b154 LibWebView: Add DevTools cookie mutation helpers
DevTools needs to edit and delete cookies from the browser process. Add
a small mutation surface to CookieJar and expose it through the DevTools
delegate while preserving the existing cookie notification path.
2026-06-11 15:03:47 +01:00
Sam Atkins
47204bd3dd LibDevTools: Report cookie storage changes
Firefox keeps the Storage table current through storesUpdate messages
from the storage actor. Forward browser cookie change notifications to
the cookies actor and classify visible rows against a fresh cookie
snapshot.

The existing cookie-change notifications report cookies that are
relevant to a specific page, whereas DevTools wants all cookies
relevant for a host, so we end up having to provide two different sets
of cookies to `notify_cookies_changed()`.
2026-06-11 15:03:47 +01:00
Sam Atkins
20f922cbdb LibWebView+LibDevTools: Populate DevTools cookies
Firefox asks the cookies actor for rows after selecting a Storage host.
Read the browser cookie jar through the DevTools delegate and serialize
matching cookies with the fields Firefox expects.

This keeps mutation support disabled, but makes existing cookies visible
in the Storage panel.
2026-06-11 15:03:47 +01:00
Sam Atkins
b2724268fe LibWebView: Notify cookie-change listeners after changing them
Cookie listeners may query the jar while handling a notification. For
example, DevTools does this when the Storage panel computes whether a
cookie was added, changed, or deleted.

Insert the cookie before sending the notification, so that listeners see
the new state, not the old one.
2026-06-11 15:03:47 +01:00
Timothy Flynn
1a99bdad29 LibWebView+UI: Add a small history application menu
This currently just contains a menu item to open about:history. But in
the future, we can add a list of recently closed / recently visited
pages as well.
2026-06-10 20:27:36 +02:00
Timothy Flynn
f72a18095d LibWebView+UI: Remove the clear-everything history store API
This was only used by the AppKit UI's history menu. We have more fine-
grained control over deleting history in about:settings#privacy.
2026-06-10 20:27:36 +02:00
Timothy Flynn
496c88d0c9 LibWebView: Add about:history to view, query and mangage browser history
This adds a WebUI to view the local browsing history, with controls to
search and delete entries. The APIs used to search history are paginated
to prevent excessive query sizes.
2026-06-10 20:27:36 +02:00
Timothy Flynn
409e5edbf1 LibURL+LibWeb+LibWebView: Move internal URLs to their own header
This nearly eliminates the compilation impact of adding a new WebUI URL.
2026-06-10 20:27:36 +02:00
Andreas Kling
37e7526367 LibGfx: Split image decoders into a separate library
Move the image loader sources and decoder-only dependencies from LibGfx
into a new LibImageDecoders library. This keeps the APNG-enabled PNG
loader out of processes that only need core graphics and image writers.

Link the ImageDecoder service, direct decoder tests, fuzzers, test-web,
and the image utility against LibImageDecoders where they still decode
images in-process.
2026-06-10 11:55:48 +02:00
Shannon Booth
5ef34ecb7a LibURL: Use libpsl for public suffix matching
Replace the generated public suffix table and custom matcher with a
direct LibURL PublicSuffixData implementation backed by libpsl. This
drops our PSL download/generator path and uses the same library already
used by libcurl.

Performance is comparable before and after, while LibURL binary size
is smaller.
2026-06-10 11:43:44 +02:00
Andreas Kling
0c7fda8735 WebContent: Sandbox renderer processes on Linux
Add opt-in Linux renderer sandbox support to WebContent and WebWorker.
Ladybird and test-web pass --enable-sandbox through when requested, and
the renderer services only install the shared sandbox when that flag is
present.

Share one renderer policy for both services. Allow resource, font,
shared library, WebGL, Wasm, audio, and local IPC paths needed at
runtime, while keeping renderer filesystem writes mediated by Landlock.

Allow Mesa and PulseAudio to probe their standard runtime state without
escaping the renderer sandbox. Return EPERM for scheduler and priority
changes so library initialization can fall back instead of crashing on a
seccomp violation.
2026-06-09 19:35:09 +02:00
Andreas Kling
ea1ecdad5a RequestServer: Sandbox the process on Linux
Add opt-in Linux sandbox support to RequestServer. Ladybird and test-web
pass --enable-sandbox through when requested, and RequestServer only
installs the sandbox when that flag is present.

Allow reads for resolver and TLS configuration, plus the configured
certificate locations. Create and allow writes to the Ladybird cache
root, so libcurl alt-svc files and HTTP disk-cache files stay inside the
single writable tree. Also allow the systemd-resolved runtime directory
when present, since /etc/resolv.conf can point there.

Extend LibSandbox with owned Landlock paths, an add-if-exists helper,
read/write Landlock access, and reusable seccomp groups for filesystem
writes and network syscalls. Include POSIX file locks and socket byte
count ioctls needed by libc resolver and cache paths. Reuse the new
Landlock helper from Compositor as well, and allow its Mesa shader cache
directory so GPU startup can populate shader cache files after
sandboxing.
2026-06-09 19:35:09 +02:00
Andreas Kling
a69fd61eaf Compositor: Sandbox the process on Linux
Add opt-in Linux sandbox support to Compositor. Ladybird and test-web
pass --enable-sandbox through when requested, and Compositor only
installs the sandbox when that flag is present.

Install the sandbox after Compositor has initialized platform, font, and
GPU state so startup probing can complete before filesystem access is
removed. Compose the runtime seccomp policy from LibSandbox building
blocks and add an explicit GPU device operations group for driver IPC
through already-open descriptors.
2026-06-09 19:35:09 +02:00
Andreas Kling
cca5a6dd37 ImageDecoder: Sandbox the process on Linux
Add --enable-sandbox to Ladybird and test-web, pass it through to
ImageDecoder, and make ImageDecoder install its Linux sandbox only when
the option is present.

The Linux implementation enables no_new_privs, configures glibc malloc
to avoid late CPU-count probes in helper threads, applies an empty
Landlock ruleset when available, and installs a seccomp filter for the
helper IPC, shared memory, threading, and decoding syscalls.

Deny plain read-only filesystem probes without granting file access, so
common runtime feature checks can observe the sandbox instead of
terminating the helper during normal decoding.
2026-06-09 19:35:09 +02:00
Sam Atkins
c7015a8647 LibWeb: Remove unused test variant metadata API
Remove internals.loadTestVariants and the IPC forwarding that reported
variant metadata back to WebView. test-web now identifies WPT variants
during collection, so no loaded document needs to expose this test-only
hook.
2026-06-09 16:48:33 +02:00
Shannon Booth
9b80ac00be LibURL: Move registrable-domain PSL lookup to PublicSuffixData
Move the registrable-domain helper from URL into PublicSuffixData and
name it find_matching_registrable_domain().

This keeps it alongside find_matching_public_suffix(), making it clear
that both APIs only return results matched from the PSL data, while
Host::public_suffix() implements the URL Standard fallback to the
top-level domain.
2026-06-08 20:19:06 +02:00
Shannon Booth
ac344a5196 LibURL: Clarify PSL matching API names
Rename PublicSuffixData's raw lookup helpers to make it clear that they
only return public suffixes matched from the PSL data.

This distinguishes them from Host::public_suffix(), which implements the
URL Standard definition and falls back to the top-level domain when no
PSL rule matches.

We need both layers because address bar handling needs the raw lookup to
decide whether input should be treated as a URL or as a search.
2026-06-08 20:19:06 +02:00
sideshowbarker
a82c7939d9 LibWeb+UI/AppKit: Implement macOS IME support
This makes macOS IME input in web content work as expected.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/9712
2026-06-08 10:23:14 +09:00
Timothy Flynn
4d51499809 LibSyntax+LibJS+LibWebView: Port the syntax highlighter to UTF-8
LibSyntax is the only remaining user of UTF-32 in the code base. Let's
use UTF-8 here.

Bonus: The tests added here for non-ASCII sources actually used to
crash the old UTF-32 implementation.
2026-06-06 18:42:18 +02:00
Timothy Flynn
87cdeda93c LibSyntax+LibJS+LibWeb+LibWebView: Remove unused syntax highlighter code
A future patch will port LibSyntax away from UTF-32. The less code that
needs to be ported, the easier that will be.
2026-06-06 18:42:18 +02:00
Tim Ledbetter
cdb8762c8f LibWebView: Add a --screenshot-path option
This option saves screenshots to the given location.
2026-06-07 00:20:19 +12:00
Callum Law
52db9e9e5d LibWebView: Remove Native.css
The last user (the built-in inspector) was removed in 810d04b.
2026-06-05 12:59:00 +01:00