Commit Graph

71 Commits

Author SHA1 Message Date
Zaggy1024
e195d4e33e LibWeb: Move canvas and media element iteration methods out of line
This reduces the number of rebuilt files when modifying
HTMLMediaElement.h and HTMLCanvasElement.h significantly.
2026-02-24 21:09:27 +01:00
Simon Farre
44e0735d9b LibWebView+UI/Qt: Allow WebContent to enter/exit the fullscreen UI
These IPC methods should be expanded in the future to allow WebContent
to specify what UI elements should be kept/removed, for example, the
navigation UI.
2026-02-23 18:44:26 +00:00
Aliaksandr Kalenik
004e5f851e LibWeb: Use ExternalContentSource for canvas painting
present() now snapshots the PaintingSurface into an ImmutableBitmap
and publishes it to the ExternalContentSource, so the rendering thread
never touches the live GPU surface — eliminating the data race
described in the ExternalContentSource commit (problem 1).

Canvas elements are registered with Page and presented once per frame
from the event loop, rather than on every individual draw call in
CRC2D::did_draw(). A dirty flag on HTMLCanvasElement ensures the
snapshot is only taken when content has actually changed, and makes
the present() call in CanvasPaintable::paint() a no-op when the
surface has already been snapshotted for the current frame.
2026-02-20 18:41:33 +01:00
Aliaksandr Kalenik
30e4779acb AK+LibWeb: Reduce recompilation impact of DOM/Node.h
Remove includes from Node.h that are only needed for forward
declarations (AccessibilityTreeNode.h, XMLSerializer.h,
JsonObjectSerializer.h). Extract StyleInvalidationReason and
FragmentSerializationMode enums into standalone lightweight
headers so downstream headers (CSSStyleSheet.h, CSSStyleProperties.h,
HTMLParser.h) can include just the enum they need instead of all of
Node.h. Replace Node.h with forward declarations in headers that only
use Node by pointer/reference.

This breaks the circular dependency between Node.h and
AccessibilityTreeNode.h, reducing AccessibilityTreeNode.h's
recompilation footprint from ~1399 to ~25 files.
2026-02-11 20:02:28 +01:00
Timothy Flynn
8d97389038 LibHTTP+Everywhere: Move the cookie implementation to LibHTTP
This will allow parsing cookies outside of LibWeb.

LibHTTP is basically becoming the home of HTTP WG specs.
2026-02-10 12:21:20 +01:00
Jelle Raaijmakers
2a2f8ef90b LibWeb+UI: Support triple clicking and dragging paragraphs
When triple clicking on text, we should select the entire paragraph, or
entire line in <input>s and <textarea>s. If the mouse button is held
down and the user starts dragging, the selection expands with additional
paragraphs or lines.

This expands on the work of Kai Wildberger (PR #7681) but was adjusted
for the work that happened previously to support double click + drag
moves and includes triple click support for our Qt UI.

Co-authored-by: Kai Wildberger <kiawildberger@gmail.com>
2026-02-06 14:18:10 +00:00
Jelle Raaijmakers
c56c933014 LibWeb+WebContent: Instantly update DPI for painting and media queries
If our UI informed the page of a DPI change, we would store the new
device pixel ratio and leave it at that. It would take a layout/style
update (e.g. by clicking the page) to actually render the page using the
new DPI. This is very visible on macOS when moving the Ladybird window
from a 1x resolution monitor to a HiDPI 2x monitor.

We now instantly update the backing stores and mark media queries for
reevaluation. Moving the Ladybird window on macOS now immediately
updates the page when dragging it to a HiDPI monitor.
2026-02-06 09:01:26 +01:00
Timothy Flynn
0482b6bb57 LibWeb+LibWebView+WebContent: Implement versioning for document cookies
This patch introduces a cookie cache in the WebContent process to reduce
blocking IPC calls when JS accesses document.cookie. The UI process now
maintains a cookie version counter per-domain in shared memory. When JS
reads document.cookie, we check whether we have a valid cached cookie by
comparing the current shared version to the last used version. If they
match, the cached cookie is returned without IPC.

This optimization is based on Chromium's shared versioning, in which it
was observed that 87% of document.cookie accesses were redundant. See:
https://blog.chromium.org/2024/06/introducing-shared-memory-versioning-to.html

Note that this cache only supports document.cookie, not HTTP Cookie
headers. HTTP cookies are attached to requests with varying URLs and
paths. The cookies that match the document URL might not match the
request URL, which we wouldn't know from WebContent. So attaching the
cached document cookie would be incorrect.

On https://twinings.co.uk, we see approximately 600 document.cookie
requests while the page loads. This patch reduces the time spent in
the document.cookie getter from ~45ms to 2-3ms.
2026-02-05 07:28:07 -05:00
Shannon Booth
c6fab541b7 LibWeb: Fix storage set broadcast event never broadcasting old value
We had skipped some steps in the spec and were:
 * Always broadcasting an old value of null, instead of what it
   actually was previously.
 * Still broadcasting a storage event even if the value had
   not changed in storage compared to the last value.

Fix both issues by returning what the old value is in the setter and
implementing the missing logic.
2026-01-21 22:27:59 +01:00
Adam Colvin
3a6d82245b LibWeb: Implement Screen.isExtended attribute
- Add WindowManagement to PolicyControlledFeature enum
- Add screen_count() virtual method to PageClient
- Store all screen rects in WebContent::PageClient, derive both
  screen_rect() and screen_count() from stored data
- Implement screen_count() overrides in SVGPageClient and PageHost
- Replace FIXME stub in Screen.cpp with spec-compliant implementation
2026-01-16 20:34:58 +01:00
Jelle Raaijmakers
bf77aeb3dc Tests/LibWeb: Support WPT variant meta tags in test-web
Add support for WPT test variants, which allow a single test file to be
run multiple times with different URL query parameters. Tests declare
variants using `<meta name="variant" content="?param=value">` tags.

When test-web encounters a test with variants, it expands that test into
multiple runs, each with its own expectation file using the naming
convention `testname@variant.txt` (e.g., `test@run_type=uri.txt`).

Implementation details:
- WebContent observes variant meta tags and communicates them to the
  test runner via a new `did_receive_test_variant_metadata` IPC call
- test-web dynamically expands tests with variants during execution,
  waking idle views after each test completion to pick up new work
- Use index-based test tracking to avoid dangling references when the
  test vector grows during variant expansion
- Introduce TestRunContext to group test run state, and store a static
  pointer to it for signal handler access

This enables proper testing of WPT tests that use variants, such as the
html5lib parsing tests (which test uri, write, and write_single modes)
and the editing/bold tests (which split across multiple ranges).
2026-01-16 16:44:13 +00: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
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
Jonathan Gamble
8f1cb4cbb0 LibWeb: Implement resizing for eligible elements and update scrollbars
Add ElementResizeAction to Page (maybe there's a better place). It's
just a mousemove delegate that updates styles on the target element.

Add ChromeMetrics for zoom-invariant chrome like scrollbar thumb
thickness, resize gripper size, paddings, etc. It's not user-stylable
but separates basic concerns in a way that a visually gifted
designer unlike myself can adjust to taste.

These values are pre-divided by zoom factor so that PaintableBox can
continue using device_pixels_per_css_pixel calls as normal.

The adjusted metrics are computed on demand from Page multiple times
per paint cycle, which is not ideal but avoids lifetime management and
atomics. Maybe someone with more surety about the painting flow control
can improve this, but it won't be a huge win. If profiling shows
this slowing paints, then Ladybird is in good shape.

Update PaintableBox to draw the resize gripper and deconflict
the scrollbars. Set apropriate cursors for scrollbars and gripper in
mousemove. We override EventHandler's cursor handling because nothing
should ever come between a man and his resize gripper.

Chrome metrics use the CSSPixels class. This is good because it's
broadly compatible but bad because they're actually different units
when zoom is not 1.0. If that's a problem, we could make a new type
or just use double.
2026-01-12 11:00:14 +00:00
Jonathan Gamble
fc22c9ea38 LibWeb+WebContent: Allow WebContent to disentangle zoom from css pixels
So Ladybird can paint scrollbar & resizer chrome at the same size
regardless of zoom level while still respecting device pixel ratio
2026-01-12 11:00:14 +00:00
Sam Atkins
c77db4135d LibWeb: Implement web-exposed available screen area
This is allowed to behave the same as the web-exposed screen area, so
we'll do that for now.
2025-12-12 10:17:00 +00:00
Luke Wilde
82bd3d3891 LibWeb: Avoid invoking Trusted Types where avoidable
Prevents observably calling Trusted Types, which can run arbitrary JS,
cause crashes due to use of MUST and allow arbitrary JS to modify
internal elements.
2025-11-06 11:43:06 -05:00
Zaggy1024
6caa2f99aa LibMedia+LibWeb: Rewrite PlaybackManager using the provider/sink model
With this commit, all PlaybackManager can do is autoplay a file from
start to finish, with no pausing or seeking functionality.

All audio playback functionality has been removed from HTMLMediaElement
and HTMLAudioElement in anticipation of PlaybackManager taking that
over, for both audio-only and audio/video.
2025-10-27 17:28:49 -07:00
Zaggy1024
0f9fa47352 LibWeb: Update media elements' page mute state via a for_each method 2025-10-27 17:28:49 -07:00
Andreas Kling
dfa796a4e4 LibJS+LibWeb: Use GC::Weak instead of AK::WeakPtr for GC-allocated types
This makes some common types like JS::Object smaller (by 8 bytes) and
yields a minor speed improvement on many benchmarks.
2025-10-17 17:22:16 +02:00
Aliaksandr Kalenik
9862d8b4a6 LibWeb: Implement pinch-to-zoom support
Adds pinch event handling that adjusts the VisualViewport scale and
offset. VisualViewport's (offset, scale) is then used to construct a
transformation matrix which is applied before display list execution.
2025-10-10 15:37:45 +02:00
Luke Wilde
74e0483ea5 LibWeb: Implement the Gamepad API with SDL3 2025-09-01 21:10:47 +02:00
ayeteadoe
3df8e00d91 LibWeb: Enable EXPLICIT_SYMBOL_EXPORT 2025-08-23 16:04:36 -06:00
Idan Horowitz
5545d38d7a LibWeb: Implement CookieStore::get(name) 2025-08-08 13:09:58 -04:00
Timothy Flynn
50fed1d65c LibWeb+LibWebView+WebContent+UI: Port the document title to UTF-16 2025-08-02 10:10:14 -07:00
Luke Wilde
3f5bc023e2 LibWeb+WebContent+UI: Remove unused same-origin policy toggle
Page::is_same_origin_policy_enabled is unused, and the original FIXME
has been implemented.
2025-07-31 18:38:03 -04:00
Timothy Flynn
67cc02ab59 LibWeb+UI: Add an explicit IPC to handle mouse leave events
The faux position we created here is adjusted by the device pixel ratio
later on, which would invoke integer overflow on screens with a DPR
greater than 1.

Instead of creating special data for a mouse move event, let's just add
an explicit leave event handler.
2025-07-28 21:26:33 +02:00
Jelle Raaijmakers
e4b2253b63 Tests: Replace load-reference-page debug action with internals method
WPT reference tests can add metadata to tests to instruct the test
runner how to interpret the results. Because of this, it is not enough
to have an action that starts loading the (mis)match reference: we need
the test runner to receive the metadata so it can act accordingly.

This sets our test runner up for potentially supporting multiple
(mis)match references, and fuzzy rendering matches - the latter will be
implemented in the following commit.
2025-07-17 12:59:11 +01:00
Aliaksandr Kalenik
aa31b69e7e LibWeb+WebContent: Delete unused page_did_layout() 2025-07-17 08:24:19 +02:00
Aliaksandr Kalenik
082053d781 LibWeb+WebContent+WebWorker: Move backing store allocation in Navigable
Making navigables responsible for backing store allocation will allow us
to have separate backing stores for iframes and run paint updates for
them independently, which is a step toward isolating them into separate
processes.

Another nice side effect is that now Skia backend context is ready by
the time backing stores are allocated, so we will be able to get rid of
BackingStore class in the upcoming changes and allocate PaintingSurface
directly.
2025-07-04 16:12:47 +02:00
Aliaksandr Kalenik
b73525ba0e LibWeb+WebContent: Delete unused "has focus" flag from paint config 2025-07-04 16:12:47 +02:00
Aliaksandr Kalenik
84b9224121 Everywhere: Implement persistence of localStorage using sqlite
This change follows the pattern of our cookies persistence
implementation: the "browser" process is responsible for interacting
with the sqlite database, and WebContent communicates all storage
operations via IPC.

The new database table uses (storage_endpoint, storage_key, bottle_key)
as the primary key. This design follows concepts from the
https://storage.spec.whatwg.org/ and is intended to support reuse of the
persistence layer for other APIs (e.g., CacheStorage, IndexedDB). For
now, `storage_endpoint` is always "localStorage", `storage_key` is the
website's origin, and `bottle_key` is the name of the localStorage key.
2025-06-12 17:04:35 +02:00
Andrew Kaster
978a3b7321 LibWeb: Move AgentType enum to its own header 2025-05-18 17:50:05 -06:00
Timothy Flynn
61c0f67c8c LibWeb+LibWebVew+WebContent+UI: Add IPC to retrieve the system clipboard
We currently have a single IPC to set clipboard data. We will also need
an IPC to retrieve that data from the UI. This defines system clipboard
data in LibWeb to handle this transfer, and adds the IPC to provide it.
2025-05-02 17:46:16 -04:00
Shannon Booth
a2cca59516 LibWeb+LibWebView+Services: Add IPC for starting WebWorker of a type
The provides some of the plumbing for a WebContent process to spin
up a WebWorker that is not just a dedicated worker.
2025-04-25 14:07:51 +02:00
Andreas Kling
bbef0e8375 LibWeb: Avoid dynamic_cast in DOM::Document::is_decoded_svg() 2025-04-18 14:45:56 +02:00
Aliaksandr Kalenik
24e2c402f5 LibWeb+WebContent: Move display list rasterization off the main thread
The display list is an immutable data structure, so once it's created,
rasterization can be moved to a separate thread. This allows more room
for performing other tasks between processing HTML rendering tasks.

This change makes PaintingSurface, ImmutableBitmap, and GlyphRun atomic
ref-counted, as they are shared between the main and rendering threads
by being included in the display list.
2025-03-31 15:58:15 +01:00
Timothy Flynn
f05b0bfd5f LibWeb+LibWebView+WebContent: Convert about:settings to a WebUI 2025-03-28 07:31:10 -04:00
Timothy Flynn
c75e40180c LibWeb+LibWebView+WebContent: Convert about:processes to a WebUI 2025-03-28 07:31:10 -04:00
Timothy Flynn
41aeb9e63a LibWeb+LibWebView+WebContent: Introduce a WebUI framework
When we build internal pages (e.g. about:settings), there is currently
quite a lot of boilerplate needed to communicate between the browser and
the page. This includes creating IDL for the page and the IPC for every
message sent between the processes.

These internal pages are also special in that they have privileged
access to and control over the browser process.

The framework introduced here serves to ease the setup of new internal
pages and to reduce the access that WebContent processes have to the
browser process. WebUI pages can send requests to the browser process
via a `ladybird.sendMessage` API. Responses from the browser are passed
through a WebUIMessage event. So, for example, an internal page may:

    ladybird.sendMessage("getDataFor", { id: 123 });

    document.addEventListener("WebUIMessage", event => {
        if (event.name === "gotData") {
            console.assert(event.data.id === 123);
        }
    });

To handle these messages, we set up a new IPC connection between the
browser and WebContent processes. This connection is torn down when
the user navigates away from the internal page.
2025-03-28 07:31:10 -04:00
Timothy Flynn
b169a98495 LibWeb+LibWebView+WebContent: Introduce a basic about:settings page
This adds a basic settings page to manage persistent Ladybird settings.
As a first pass, this exposes settings for the new tab page URL and the
default search engine.

The way the search engine option works is that once search is enabled,
the user must choose their default search engine; we do not apply any
default automatically. Search remains disabled until this is done.

There are a couple of improvements that we should make here:

* Settings changes are not broadcasted to all open about:settings pages.
  So if two instances are open, and the user changes the search engine
  in one instance, the other instance will have a stale UI.

* Adding an IPC per setting is going to get annoying. It would be nice
  if we can come up with a smaller set of IPCs to send only the relevant
  changed settings.
2025-03-22 17:27:45 +01:00
Timothy Flynn
843209c6a9 LibWeb+LibWebView+WebContent: Add an about:processes page
The intent is that this will replace the separate Task Manager window.
This will allow us to more easily add features such as actual process
management, better rendering of the process table, etc. Included in this
page is the ability to sort table rows.

This also lays the ground work for more internal `about` pages, such as
about:config.
2025-03-19 10:03:17 -04:00
Aliaksandr Kalenik
394073f611 LibWeb: Rename internals.signalTextTestIsDone() to signalTestIsDone()
In upcoming change this function will be used for ref-tests as well.
2025-03-18 20:09:46 +01:00
Timothy Flynn
810d04b3f4 LibWeb+LibWebView+WebContent: Remove the built-in Inspector 2025-03-15 19:09:40 +01:00
Timothy Flynn
5810c8073e LibWeb+LibWebView+WebContent: Begin implementing simple site islotation
Site isolation is a common technique to reduce the chance that malicious
sites can access data from other sites. When the user navigates, we now
check if the target site is the same as the current site. If not, we
instruct the UI to perform the navigation in a new WebContent process.

The phrase "site" here is defined as the public suffix of the URL plus
one level. This means that navigating from "www.example.com" to
"sub.example.com" remains in the same process.

There's plenty of room for optimization around this. For example, we can
create a spare WebContent process ahead of time to hot-swap the target
site. We can also create a policy to keep the navigated-from process
around, in case the user quickly navigates back.
2025-03-11 12:10:42 +01:00
Timothy Flynn
62912b985a LibWeb+WebContent: Take advantage of IPC encoding improvements
This removes a couple of places where we were constructing strings or
vectors just to transfer data over IPC. And passes some values by const&
to remove clangd noise.
2025-03-09 11:14:20 -04:00
Timothy Flynn
2c4b420acc LibWeb+LibWebView+WebContent: Inform the UI about DOM mutations
This will allow our DevTools server to inform the Firefox DevTools
client about DOM mutations.
2025-03-08 01:25:55 +01:00
Timothy Flynn
b11ba4cc90 LibWeb: Clear the document's page's focused navigable upon destruction
We set the page's focused navigable upon mouse-down events from the UI.
However, we neglected to ever clear that focused navigable upon events
such as subsequent page navigations. This left the page with a stale
reference to a no-longer-active navigable. The effect was that any key
events from the UI would not be sent to the new page until either the
reference was collected by GC, or another mouse-down event occurred.

In the test added here, without this fix, the text sent to the input
element would not be received, and the change event would not fire.
2025-03-02 17:27:24 -05:00
Sam Atkins
bfd7ac1204 LibWeb+WebContent+UI: Support image cursors
The `cursor` property accepts a list of possible cursors, which behave
as a fallback: We use whichever cursor is the first available one. This
is a little complicated because initially, any remote images have not
loaded, so we need to use the fallback standard cursor, and then switch
to another when it loads.

So, ComputedValues stores a Vector of cursors, and then in EventHandler
we scan down that list until we find a cursor that's ready for use.

The spec defines cursors as being `<url>`, but allows for `<image>`
instead. That includes functions like `linear-gradient()`.

This commit implements image cursors in the Qt UI, but not AppKit.
2025-02-28 13:50:13 +01:00