Commit graph

104 commits

Author SHA1 Message Date
Timothy Flynn
8ad1c72ed3 LibWeb+LibWebView+Services: Add a flag to enable experimental interfaces
This adds the --expose-experimental-interfaces command line flag to
enable experimental IDL interfaces. Any IDL interface with Experimental
in its exposed attributes will be disabled by default.

The problem is that by stubbing out or partially implementing interfaces
in LibWeb, we actually make some sites behave worse. For example, the
OffscreenCanvas interface being exposed makes sites believe we fully
support it, even though we don't. If the interface was not exposed,
these sites may fall back to ordinary canvas objects. Similarly, to
use YouTube, we currently have to patch out MSE interfaces.

This flag will allow developers to iteratively work on features,
without breaking such sites. We enable experimental interfaces during
tests.
2026-02-17 22:17:50 +01:00
Timothy Flynn
b357d3c3c8 LibWebView+WebContent: Move test-mode special handling to the UI process
We will need to propagate test mode behavior to both the WebContent and
WebWorker processes. By moving this handling to the UI process, we will
only need to update one location.
2026-02-17 22:17:50 +01:00
Timothy Flynn
7d60d0bfb7 LibHTTP+LibWebView+RequestServer: Allow users to set disk cache limits
This adds a settings box to about:settings to allow users to limit the
disk cache size. This will override the default 5 GiB limit. We do not
automatically delete cache data if the new limit is suddenly less than
the used disk space; this will happen on the next request. This allows
multiple changes to the settings in a row without thrashing the cache.

In the future, we can add more toggles, such as disabling the disk
cache altogether.
2026-02-13 10:20:52 -05:00
Timothy Flynn
e6c008a269 LibWeb+RequestServer: Attach HTTP cookie headers from RequestServer
We currently attach HTTP cookie headers from LibWeb within Fetch. This
has the downside that the cookie IPC, and the infrastructure around it,
are all synchronous. This blocks the WebContent process entirely while
the cookie is being retrieved, for every request on a page.

We now attach cookie headers from RequestServer. The state machine in
RequestServer::Request allows us to easily do this work asynchronously.
We can also skip this work entirely when the response is served from
disk cache.

Note that we will continue to parse cookies in the WebContent process.
If something goes awry during parsing. we limit the damage to that
process, instead of the UI or RequestServer.

Also note that WebSocket requests still have cookie headers attached
attached from LibWeb. This will be handled in a future patch.

In the future, we may want to introduce a memory cache for cookies in
RequestServer to avoid IPC altogether as able.
2026-02-10 12:21:20 +01:00
Timothy Flynn
70482687a2 LibWebView+UI: Always ask the user where to save screenshots
We currently always save screenshots to the Downloads folder. We will
now always ask for a save location.

This will just let an upcoming feature to save images from web pages
behave the same way. We will want the user to be able to choose a file
name, since the file name from the URL might be nonsense or already
exist.
2026-02-05 07:27:34 -05:00
Andreas Kling
64d033b31a LibWebView+test-web: Print heap explorer URL after dumping GC graph
When dumping a GC graph, we now write the output as a .js file
containing `var GC_GRAPH_DUMP = <json>;` instead of raw JSON.
This allows gc-heap-explorer.html to load the dump via a
dynamically created <script> element, avoiding CORS restrictions
that prevent file:// pages from fetching other file:// URLs.

After dumping, both the browser and test-web print a clickable
file:// URL that opens the heap explorer with the dump pre-loaded.

The heap explorer's drag-and-drop file picker also accepts both
the new .js format and plain .json files.
2026-02-01 22:46:09 +01:00
Sam Atkins
cdf55ea371 WebContent+LibWebView: Rename --layout-test-mode flag to --test-mode
This name has been outdated for a while, as it's enabled when running
any kind of test, not just layout tests.
2026-01-20 06:58:16 -05:00
Timothy Flynn
bc1cafc716 LibHTTP+LibWebView+RequestServer: Allow using the disk cache during WPT
We currently disable the disk cache because the WPT runner will run more
than one RequestServer process at a time. The SQLite database does not
handle this concurrent read/write access well.

We will now enable the disk cache with a per-process database. This is
needed to ensure that WPT Fetch cache tests are sufficiently handled by
RequestServer.
2026-01-19 08:02:14 -05:00
Andreas Kling
18aee32084 RequestServer: Add --resource-map option for URL-to-file substitution
This adds support for intercepting network requests and serving local
file content instead. When a URL matches an entry in the substitution
map, the local file is served while preserving the original URL's
origin for cross-origin checks.

Usage:
    Ladybird --resource-map=/path/to/map.json

The JSON file format is:
    {
      "substitutions": [
        {
          "url": "https://example.com/script.js",
          "file": "/path/to/local/script.js",
          "content_type": "application/javascript",
          "status_code": 200
        }
      ]
    }

Fields:
  - url (required): Exact URL to intercept (query string and fragment
    are stripped before matching)
  - file (required): Absolute path to local file to serve
  - content_type (optional): Override Content-Type header (defaults to
    guessing from filename)
  - status_code (optional): HTTP status code (defaults to 200)

This is incredibly useful for debugging production websites: you can
intercept any script, stylesheet, or other resource and replace it with
a local copy containing your own debug instrumentation, console.log
statements, or experimental fixes - all without modifying the actual
site or setting up a local dev server.
2026-01-19 10:23:26 +01:00
Andreas Kling
770811e343 LibDevTools: Only send network response bodies when DevTools connected
To avoid unnecessary IPC traffic, we now only send network response
bodies when a DevTools client is connected.

This requires tracking DevTools connection state in ViewImplementation
so we can propagate it to new WebContent processes created during
cross-site navigation.
2026-01-15 20:10:19 +01:00
Andreas Kling
681d00c218 LibDevTools: Pass request initiator type to network panel
Propagate the request initiator type (e.g., "xmlhttprequest", "fetch",
"script", "stylesheet") from LibWeb through the IPC layer to DevTools.

This enables Firefox DevTools to correctly identify XHR/fetch requests
and display appropriate cause types in the Network panel's "Initiator"
column.
2026-01-15 20:10:19 +01:00
Andreas Kling
31ffd2e8e5 LibDevTools: Add request and response body viewing to network panel
This adds support for viewing request payloads (POST data) and response
bodies in the Firefox DevTools network panel.

Request bodies are captured when network requests start and passed
through IPC to the NetworkEventActor, which returns them via the
getRequestPostData protocol method.

Response bodies are streamed via a new IPC message as data is received,
accumulated in NetworkEventActor (with a 10MB size limit to prevent
memory issues), and returned via getResponseContent. Text content is
returned as UTF-8, while binary content (images, etc.) is base64.
2026-01-15 20:10:19 +01:00
Andreas Kling
cd8778f662 LibDevTools: Stream console messages instead of polling by index
Previously, console messages were sent using an index-based system where
DevTools would be notified of new message indices and then request them
in batches. This created synchronization issues during page navigation
when the WebContent process resets while DevTools still has stale index
state.

This changes to a push-based model where console messages are sent
immediately as resources when they are logged, matching how Firefox
DevTools handles console messages. Each message is pushed through IPC
and forwarded to DevTools as a "console-message" or "error-message"
resource.

This eliminates the need for index tracking in FrameActor and simplifies
the entire console message pipeline from WebContent through to DevTools.
2026-01-15 20:10:19 +01:00
Andreas Kling
9b8e822390 LibDevTools: Send navigation events to Firefox DevTools
When a page navigates, send document-event resources with
"will-navigate" and tabNavigated messages so Firefox DevTools
can follow along and clear the Network panel appropriately.
2026-01-15 20:10:19 +01:00
Andreas Kling
cf010885d5 LibDevTools: Add Firefox DevTools network monitoring support
Hook ResourceLoader to emit network request lifecycle events through
IPC to the UI process, where FrameActor creates NetworkEventActor
instances that serialize requests using Firefox's Remote Debug Protocol.

The Network panel now shows requests with method, URL, status, MIME
type, size, and timing information. Several features remain stubbed
(POST data, response content, cause detection) marked with FIXMEs.
2026-01-15 20:10:19 +01:00
Andreas Kling
419afa544c LibWebView: Notify all views when shared WebContent crashes
When multiple views share a WebContent process (e.g. parent and child
views created via window.open()), we need to notify ALL of them when
the process crashes, not just one.

Previously, each view would overwrite the single crash callback on
WebContentClient, so only the last view to initialize would be notified.

This adds WebContentClient::notify_all_views_of_crash() which iterates
over all registered views and notifies each one. Child views also now
propagate crashes to their parent, and can be disconnected between
tests to prevent stale crashes from affecting subsequent tests.
2026-01-13 23:57:46 +01:00
Jonathan Gamble
7385569a02 LibWeb: Selection toString focused text control delegation
Allows selected text in form controls to be copied to clipboard.
2026-01-02 18:40:05 +01:00
Timothy Flynn
4e79d86d03 LibWebView: Enable the HTTP disk cache by default
This enables the disk cache and flips the related command line flag to
allow disabling it. We've reached a point where it works well, so this
will let us get more mileage on it.
2025-12-02 12:19:42 +01:00
Timothy Flynn
adcf5462af LibWeb+WebContent: Rename the http-cache flag to http-memory-cache
Rather than having http-cache and http-disk-cache, let's rename the
former to http-memory-cache to be extra clear what we are talking about.
2025-12-02 12:19:42 +01:00
Timothy Flynn
b2c112c41a LibWebView+RequestServer: Add a simple test mode for the HTTP disk cache
This mode allows us to test the HTTP disk cache with two mechanisms:

1. If RequestServer is launched with --http-disk-cache-mode=testing, it
   will cache requests with a X-Ladybird-Enable-Disk-Cache header.

2. In test mode, RS will include a X-Ladybird-Disk-Cache-Status response
   header indicating how the response was handled by the cache. There is
   no standard way for a web request to know what happened with respect
   to the disk cache, so this fills that hole for testing.

This mode is not exposed to users.
2025-11-20 09:33:49 +01:00
Timothy Flynn
a853bb43ef LibWebView+UI: Pass RequestServerOptions to Application implementations
This will be needed by test-web.
2025-11-20 09:33:49 +01:00
Tim Ledbetter
e3cdeada77 LibWeb: Add --headless=manual option to run until explicit exit
This headless mode will stay open until it is closed by manually or by
calling `window.close()`.
2025-11-14 08:58:18 -05:00
Timothy Flynn
c80b698589 LibWebView+UI: Remove some now-superfluous debug menu items
No need to keep these actions around, users can use the about:settings
page instead.
2025-11-12 09:06:21 -05:00
Timothy Flynn
c34119cb29 LibWebView: Add a settings section to manage browsing data caches
This adds a section to allow users to clear the HTTP disk cache and
cookies / local storage / session storage. There are a few options to
limit this action to a specific time range (e.g. "last hour"). The
user is informed how much disk space is being used currently, and how
much will be removed given the selected time range.

The idea is that in the future, we can add more settings here to auto-
delete data on exit, disable caching altogether, etc.
2025-11-12 09:06:21 -05:00
Timothy Flynn
3f61f0f189 RequestServer: Add a time parameter to the clear cache endpoint
This allows removing cache entries last accessed since a provided
timestamp.
2025-11-12 09:06:21 -05:00
Timothy Flynn
e0a8eb3767 LibWeb+WebContent: Hook Fetch's HTTP cache into the clear-cache action
And fix a typo in an invocation to clear the cache.
2025-11-05 18:27:36 +01:00
Luke Wilde
4ede2cdf18 LibWebView+WebContent: Allow setting the default time zone
This is used by tests to set the default time zone to UTC.

This is because certain tests create JavaScript Date objects, which are
in the current timezone.
2025-10-23 14:42:45 +02:00
Sam Atkins
41b4292447 LibDevTools+LibWebView: Implement initial accessibility tree view
This is enough for Firefox to display the Accessibility tab, containing
our accessibility tree which can be inspected. Most information is
blank for now.

There's quite a bit of duplication between AccessibilityWalkerActor and
WalkerActor - it might be worth trying to make a base class once the
details are figured out. Frustratingly, the two don't work quite the
same: for a lot of messages that would be sent to WalkerActor, the
accessibility equivalent is sent to the AccessibilityNodeActor instead.

Co-authored-by: Tim Flynn <trflynn89@pm.me>
2025-10-20 10:51:19 +01:00
Andreas Kling
383dd28217 LibWebView: Add CLI option to run with content filters disabled
Let's have a way to run all the JavaScript the web wants to give us.
This was previously available as a Debug menu option, and this makes
it available from process startup.
2025-10-17 11:24:57 +02:00
Timothy Flynn
163e8e5b44 LibWebView+RequestServer: Support clearing the HTTP disk cache
This is a bit of a blunt hammer, but this hooks an action to clear the
HTTP disk cache into the existing Clear Cache action. Upon invocation,
it stops all existing cache entries from making further progress, and
then deletes the entire cache index and all cache files.

In the future, we will of course want more fine-grained control over
cache deletion, e.g. via an about:history page.
2025-10-14 13:40:33 +02:00
Timothy Flynn
42eaea1043 LibWebView: Add a command line flag to enable the HTTP disk cache
This adds a RequestServerOptions structure to hold this option and the
only other RS option we currently have (certificates).
2025-10-14 13:40:33 +02:00
Timothy Flynn
187d02c45d LibDatabase+LibWebView: Extract our SQLite wrapper to its own library
It currently lives in LibWebView as it was only used for cookies and
local storage, both of which are managed in the UI process. Let's move
it to its own library now to allow other processes to use it, without
having to depend on LibWebView (and therefore LibWeb).
2025-10-14 13:40:33 +02:00
Timothy Flynn
e57176b484 LibWebView: Move headless clipboard management to LibWebView
We only supported headless clipboard management in test-web. So when WPT
tests the clipboard APIs, we would blindly try to access the Qt app,
which does not exist.

Note that the AppKit UI has no such restriction, as the NSPasteboard is
accessible even without a GUI.
2025-10-10 15:10:03 -04:00
ayeteadoe
f4c8fd4bef LibCore+LibWebView+UI/Qt: Support TimeZoneWatcher on Windows
To detect system time zone changes on Windows, the event we need to look
for is WM_TIMECHANGE. The problem is how the callback with said message
actually gets invoked is very particular. (1) We must have an active
message pump (event loop) for the message to ever be processed. (2) We
must be a GUI application as WM_TIMECHANGE messages are seemingly sent
to top level windows only. It doesn't say that in the docs for the
event, but attempts of creating a LibTest-based application with a
message pump and a message only window and never receiving the event
point to that probably being true.

This workaround is built off the fact that Qt's message pump defined
internally in QEventDispatcherWin32::processEvents does in fact receive
WM_TIMECHANGE events, even though it is not exposed as a QEvent::Type.
Given the requirements stated above it makes sense that it works here as
the message pump is executing in a QGuiApplication context. So we use a
native event filter to hook into the unexposed WM_TIMECHANGE event and
forward it along to the on_time_zone_changed() callback.

Note that if a Windows GUI framework is done in the future, we'll have
to re-add support to ensure the TimeZoneWatcher still gets invoked.
2025-10-05 15:46:15 +02:00
Timothy Flynn
ca082d6d73 LibWebView+UI: Move clipboard handling from the WebView to the App
Clipboard handling largely has nothing to do with the individual web
views. Rather, we interact with the system clipboard at the application
level. So let's move these implementations to the Application.
2025-09-19 06:38:52 -04:00
Timothy Flynn
8b2187bf92 LibWebView+UI: Generate the entire Inspect menu
Now that all the actions in the Inspect menu are generated, we can
generate the menu itself.
2025-09-18 07:27:24 -04:00
Timothy Flynn
14d49d5a3a LibWebView+UI: Generate action to enable/disable DevTools 2025-09-18 07:27:24 -04:00
Timothy Flynn
6d30b0f4d4 LibWebView+UI: Generate actions to open about: pages 2025-09-18 07:27:24 -04:00
Timothy Flynn
ce331cbcd5 LibWebView+UI: Add an Application method to open a URL in a new tab
This lets us avoid each UI needing to handle link clicks directly, and
lets actions stored in LibWebView avoid awkwardly going through the link
click callbacks to open URLs.
2025-09-18 07:27:24 -04:00
Callum Law
7a9b1a8033 LibWebView: Show a better error for invalid download dir in headless
Previously if the directory returned by `downloads_directory()` didn't
exist (or wasn't a directory) when taking a screnshot in headless mode
we try to ask the user for the download directory and fail with the
unhelpful error: QWidget: Must construct a QApplication before a QWidget
2025-09-16 10:39:20 -04:00
Timothy Flynn
9684e6dbc5 LibWebView+UI: Generate the zoom menu 2025-09-11 14:23:45 -04:00
Timothy Flynn
7d6ea99d0d LibWebView+UI: Generate the preferred color, contrast, and motion menus 2025-09-11 14:23:45 -04:00
Timothy Flynn
9c99c48f47 LibWebView+UI: Generate the application debug menu
By migrating the debug menu to LibWebView, the AppKit and Qt UIs are now
in sync - the AppKit UI was previously missing some actions.

Further, this inadvertently fixes bugs around applying debug settings to
new web views, especially across site-isolated processes. We were
previously not applying settings appropriately; this now "just works" in
the LibWebView infra.
2025-09-11 14:23:45 -04:00
Timothy Flynn
5d8d9b337a LibWebView+UI: Generate application context menus
This migrates all duplicated context menus from the UIs to LibWebView.
The context menu actions are now largely handled directly in LibWebView,
with some UI-specific callbacks added to display e.g. confirmation
dialogs.

Actions that only ever apply to a specific web view are stored on the
ViewImplementation itself. Actions that need to be dynamically applied
to the active web view are stored on the Application.
2025-09-11 14:23:45 -04:00
Timothy Flynn
2632b1375b LibWebView+UI: Extract some UI-specific displays to Application helpers
This is preparation for moving application menus to LibWebView. We will
need a way to display these dialogs from outside of the UI layer.
2025-09-11 14:23:45 -04:00
Andreas Kling
8833ffaf5d LibWebView: Enable HTTP cache by default
The HTTP cache is now stable enough that we can ask more people to help
us testing it. So let's turn it on by default! It can be turned off with
--disable-http-cache if needed.
2025-09-08 12:53:21 +02:00
Jelle Raaijmakers
9e4b6c1ded LibWebView: Remove m_in_shutdown in favor of event loop's exit request 2025-08-17 20:51:56 -04:00
Timothy Flynn
ded337cfec LibWebView: Gracefully handle RequestServer death
This works exactly the same as ImageDecoder death handling.
2025-08-10 11:02:50 +02:00
Timothy Flynn
e421c233a6 LibWebView: Ignore ImageDecoder death during process shutdown 2025-08-10 11:02:50 +02:00
Timothy Flynn
50fed1d65c LibWeb+LibWebView+WebContent+UI: Port the document title to UTF-16 2025-08-02 10:10:14 -07:00