Commit graph

2014 commits

Author SHA1 Message Date
Aliaksandr Kalenik
d725c36129 LibWeb: Store cached display list commands without resources
Cached display list command sequences used to carry their own
DisplayListResourceStorage. That kept resource ID sets and referenced
fonts, images, video frames, and nested display lists alive on every
cached phase, even though the command bytes already contain enough
information to discover those references when they are needed.

This makes cached command sequences store only command bytes. Resource
references are collected transiently from those bytes when a cache entry
is installed or invalidated. The navigable's central display list
resource storage now keeps cache reference counts, so compositor pruning
retains resources used by live cached commands without duplicating
storage in each sequence.
2026-05-31 00:21:25 +01:00
Shannon Booth
bc94e815ad LibWeb/HTML: Account for replaced cross-origin descriptors
Synthesize cross-origin Window and Location method/accessor wrappers
from the original IDL members instead of reading the current own
property descriptor, which may have been replaced by page script.
This prevents crashes and preserves the required cross-origin behavior
when properties such as frames or focus are overridden.

This requires making Location initialization define its internal own
properties through the ordinary object path, avoiding cross-origin
[[DefineOwnProperty]] during lazy Location creation.

These tests were previously not crashing in test-web as they were
improperly imported from WPT.
2026-05-30 22:55:44 +02:00
Andreas Kling
acc86e9eb1 LibWeb: Add a caret hit-test debug overlay
Add a debug-menu toggle for caret hit testing at the mouse position.
Paint the insertion rect and log the result so selection bugs can be
inspected without temporary probes.

Request frames and repaint invalidation when the overlay state changes.
Also repaint when the caret rect moves within the same text node.
2026-05-30 13:50:48 +02:00
Andreas Kling
7445cff5e8 LibWeb: Use retained data for hit testing
Build a hit-test display list while recording paint output. Use it as
source of truth for point hit testing instead of recursively walking the
paintable tree in reverse paint order.

The retained list records target paintables, visual context indices,
border radii, caret rects, and line metadata needed by hit testing. It
also keeps a spatial index so point queries inspect nearby items before
checking containment in paint order.

Refresh scroll state before hit testing so visual context transforms use
current scroll offsets. Add text tests for rounded hit regions and
selection across non-text content.
2026-05-30 13:50:48 +02:00
Tim Ledbetter
709c10f8ec LibWeb: Let range inputs stretch in grid containers
Previously, the UA stylesheet gave range inputs a definite
`width: 20ch`. This prevented range inputs from filling their grid
track. We now source the default width and height from a new
`RangeInputBox` type. This approach matches the implementation of other
input types.
2026-05-30 12:17:58 +01:00
Shannon Booth
97abc707c7 LibWeb/Bindings: Generate buffer typedefs as variants
Represent BufferSource and ArrayBufferView as ordinary IDL typedefs over
their underlying union types, instead of special casing in the IDL
generator. This allows the union conversion/return machinery handle
these types consistently with other typedefs, which removes buffer
specific paths from the IDL generator.

This necessitates changing the WebIDL::BufferSource and
WebIDL::ArrayBufferView classes as views over these variants. This
replaces the old GC backed BufferableObject wrapper structure and
provide convenience helpers to determine things such as the byte length,
byte offset, backing buffer, and typed-array APIs.
2026-05-30 11:22:08 +02:00
Shannon Booth
bf29eb2a89 LibWeb: Remove various case of unneeded use of GC::Root 2026-05-29 17:21:17 +02:00
R-Goc
520a7c8ebd AK+LibWeb: Centralize FFI helper functions
This commit creates a central FFIHelpers.h header which implements
common conversions from FFI.
2026-05-28 14:15:43 -05:00
Zaggy1024
99fef15c7f LibWeb: Remove now-unused HTMLMediaElement::toggle_playback()
This function never worked properly anyway.
2026-05-28 10:30:20 -05:00
Zaggy1024
f02e9174c7 LibWeb: Don't use toggle_playback() in MediaControls' play/pause button
This function checks potentially_playing(), which means the button
doesn't do anything if the player is buffering. We don't want that.
2026-05-28 10:30:20 -05:00
Zaggy1024
14a85b0c33 LibWeb: Fire the progress event when new media data is received
Also, update the ready state when the progress event is fired.
Otherwise, we won't autoplay if 5 seconds of data aren't available in
on_metadata_parsed().
2026-05-28 10:30:20 -05:00
Zaggy1024
e8dd9a1716 LibWeb: Remove two unused static vectors in MediaControls.cpp 2026-05-28 10:30:20 -05:00
Zaggy1024
45c2681943 LibWeb: Make buffered ranges visible on the media controls' timeline
The timeline will appear brightened in portions that are buffered,
including sections prior to the current position.
2026-05-28 10:30:20 -05:00
Zaggy1024
948e625f32 LibWeb: Simplify formatting of media timeline progress width style
Factoring this out will let us reuse it for the buffered ranges.
2026-05-28 10:30:20 -05:00
Zaggy1024
8a85cafd36 LibWeb: Move media controls' timeline fill to an inner div
This will allow us to contain the buffered ranges within the timeline's
area.
2026-05-28 10:30:20 -05:00
Timothy Flynn
47b6f5e607 LibWeb: Do not send every decoded favicon to the UI process
If a page contains multiple <link rel="icon"> elements, we would send
each of them to the UI process. We would then just use whichever was
sent last as the favicon in the UI.

We now only send the favicon that was chosen for the document. This
will either be the largest icon decoded from a link element, or the
singular fallback icon.
2026-05-28 16:01:30 +02:00
Timothy Flynn
5f3ea017f5 LibWeb: Select the largest decoded favicon as the active page favicon
We currently pick the first favicon in reverse tree order. But we are
encouraged by the spec to pick the most appropraite icon. We now
consider the size of the decoded icon, and choose the largest.
2026-05-28 16:01:30 +02:00
sideshowbarker
03f6f25b11 LibWeb: Skip user-select:none when extracting selected text
Problem: Select All (Ctrl+A or the context menu) followed by Ctrl+C
unexpectedly copies text from elements with user-select:none — breaking
compat with Chrome and Firefox, which both exclude user-select:none
content from the clipboard.

Cause: Navigable::selected_text() walks the selection range via
visible_text_in_range() and concatenates each text node’s data. The walk
filters out nodes without a layout, but not nodes whose used value of
user-select is ‘none’.

Fix: Add a user-select check at each visible_text_in_range() walk point.
The Selection range itself is left unchanged. Selection.toString() still
returns the full text per spec — but the clipboard-extraction path now
excludes user-select: none subtrees, per spec
2026-05-28 12:15:21 +01:00
Tim Ledbetter
3049d77979 LibWeb: Use advance width for canvas text alignment
Previously, `text_path() used the glyph outline bounding box width to
compute text alignment offsets and maxWidth scaling. The bounding box
only covers visible glyph outlines, excluding the advance of spaces and
glyph side bearings. This caused text with `textAlign` "end", "right",
or "center" to be mispositioned. We now use the sum of glyph run
advance widths instead.
2026-05-28 10:40:44 +02:00
Vanand Gasparyan
f3a3488cda Rust: Set import granularity to Item
By default, `rustfmt` persists the import granularity. In practice, most
Rust code has import granularity "Module" due to LSP's actions.

"Item" gets rid of import groupings and achieves cleaner diffs and
better conflict resolution. Better greppability is a positive side
effect.

Note: it's an unstable rustfmt feature. `cargo +nightly fmt` must be
used instead of `cargo fmt`.
2026-05-28 06:52:18 +02:00
Zaggy1024
d36647427e LibWeb: Always set media track enabled state
...and avoid telling the media element about it unless the track is
actually associated. The media element should set its state later when
it queries the status upon metadata parsing.
2026-05-27 19:47:22 -05:00
Aliaksandr Kalenik
790d5c0489 Compositor: Drop redundant context state
CompositorState treats presence in m_contexts as the lifetime state
for a compositor context. create_context() creates the entry and
destroy_context() removes it, so ContextState::is_registered duplicated
the map membership invariant.

The top-level-traversable bit was also duplicate information. The
only compositor use was backing-store padding while a window resize is
in progress, and page-presenting contexts are already identified by
PagePresentationRegistration::Yes. Normalize resize-in-progress to No
for non-page-presenting contexts, then remove the flag from
CompositorState, the backing-store API, and the compositor IPC boundary.
2026-05-27 20:29:36 +01:00
Andreas Kling
d7f1994606 LibWeb: Keep embedded about:blank canvases on default scheme
Only give initial and empty loaded about:blank documents the implicit
light/dark supported schemes when they belong to a top-level navigable.
Embedded empty documents should not negotiate the page preferred dark
scheme while their embedding element remains light, since that forces an
opaque dark iframe canvas.

Add text coverage for both initial and navigated embedded about:blank
documents under a dark preferred scheme.
2026-05-27 20:57:38 +02:00
Andreas Kling
ab4356edea LibWeb: Let about:blank use dark color schemes
Opt empty about:blank documents into both light and dark supported
color schemes. This covers both navigation-created about:blank documents
and the initial about:blank document created with a browsing context, so
dark mode can choose the dark Canvas color before page content arrives.
2026-05-27 20:57:38 +02:00
Aliaksandr Kalenik
b36e6c9b97 Compositor+LibWeb: Pass AVC trees separately from display lists
Display lists owned the accumulated visual context tree through a
ref-counted pointer. That tied visual-context state to display-list
lifetime and made compositor updates treat the two as one unit, even
though AVC trees need to become independently updateable compositor
state.

Make accumulated visual context trees plain versioned values, have each
display list store the compatible tree version, and pass the matching
tree alongside display-list updates and replay calls. Replay verifies
that the provided tree matches the display list before executing it.

This prepares the compositor for receiving AVC tree updates separately
from display-list updates: it now accepts the tree as a separate update
parameter, stores it next to the display list, and uses that stored tree
for replay and async-scroll hit testing. Nested display-list resources
carry their own tree snapshots for the same version check.
2026-05-27 18:29:42 +01:00
Andreas Kling
1e3653364b LibWeb: Pause animated images while hidden
Stop HTMLImageElement animation timers when their document becomes
hidden, and resume them only if visibility was what paused them. This
keeps inactive tabs from advancing animated image frames and requesting
more decoded frames from ImageDecoder.

Also avoid starting newly loaded animated images while their document is
hidden, so images loaded in background tabs wait until the page becomes
visible before animating.
2026-05-27 18:44:42 +02:00
Aliaksandr Kalenik
9ab311507e LibWeb+UI: Synthesize ctrl-wheel events for pinches
Trackpad pinches applied directly as visual viewport zoom, so pages
could not observe the gesture or cancel the browser default. Canvas
apps such as maps expect the ctrl-wheel path instead.
2026-05-27 12:53:08 +02:00
Luke Wilde
80e101a43d LibWeb/HTML: Add unsigned big integer helpers to TransferData 2026-05-27 02:44:46 +01:00
Shannon Booth
2a2b0bf91a LibWeb: Use the node document realm for image requests
An HTMLImageElement can be adopted across documents while an image
update is still pending. In that case the element's wrapper realm can
still be the old iframe realm, but the image request must be created and
fetched using the element's current node document.

Using the old iframe realm associates the request with the removed
iframe's document-owned image request cache, so the adopted image can
fail to complete in the parent document. Use document().realm() when
creating/updating/fetching image requests so adopted images continue
loading in their new document.

Add a regression for an image created in an iframe, then adopted into
the parent after the iframe is removed.

Chromium and Webkit do not fire a load event for the test, but Firefox
does. All load the image, where we previously did not.

See: https://github.com/whatwg/html/issues/8492
2026-05-27 02:40:53 +01:00
Luke Wilde
7e6d4b7b7b LibWeb+LibWebView: Move WebWorkerClient into LibWebView
This mirrors WebContentClient and allows Workers to directly interact
with WebView APIs such as the CookieJar.
2026-05-27 02:27:19 +01:00
Luke Wilde
c2dbd52982 LibWebView+WebContent+WebWorker: Move worker ownership into LibWebView
This lays the groundwork to allow shared workers, nested workers (i.e.
workers owned by workers) and service workers to function independently
of WebContent.
2026-05-27 02:27:19 +01:00
Shannon Booth
df6c3fcfaa LibWeb/Bindings: Remove GenerateAsRequired handling from IDL generator
This was used before we generated dictionary definitions using the IDL
generator, and no longer serves the purpose it used to.
2026-05-26 21:43:57 +02:00
Shannon Booth
7893f02150 LibWeb: Port a bunch of GC::Root to GC::Ref / GC::Ptr 2026-05-26 21:43:55 +02:00
Pavel Shliak
b542552f1e LibWeb: Map embedded content align to vertical-align 2026-05-26 09:35:16 +02:00
Veeti Paananen
2b365120f8 LibWeb: Allow HTMLLabelElement to delegate activation behavior
When a label's activation behavior runs for a form-associated custom
element whose shadow root has delegatesFocus: true, the shadow host is
not itself a focusable area. The old is_focusable() check prevented
run_focusing_steps from ever being called, which means
get_focusable_area never got a chance to descend into the shadow root
via focus_delegate.

Fixes WPT custom-elements/form-associated/label-delegatesFocus.html.
2026-05-26 09:29:13 +02:00
Andreas Kling
23c1e1d2b5 LibWeb: Avoid creating RAF driver when canceling frames
Treat a missing animation frame callback driver as an empty map when
canceling a frame. This keeps media controls finalization from
allocating while GC is collecting unreachable media elements.

Cover this with a media controls GC text test.
2026-05-26 09:09:11 +02:00
aplefull
201e380854 LibWeb: Allow UTF-8 detection for file: scheme 2026-05-25 23:45:28 +02:00
Andreas Kling
2bdb35aad5 LibWeb: Preserve full invalidation for pixel ratio changes
Reuse the existing display-list invalidation signal from viewport
updates to distinguish ordinary resizes from DPR and zoom changes.
The latter still need full style invalidation because snapped border
and outline widths depend on device_pixels_per_css_pixel even when
style does not otherwise depend on viewport metrics.

Add a text test for changing devicePixelRatio with subpixel border
and outline widths.
2026-05-25 19:18:10 +02:00
Andreas Kling
ceb25e10d4 LibWeb: Avoid full viewport resize style invalidations
Use the viewport metric dependency flags to restyle only elements whose
computed values can change after a viewport resize. Descendants that
inherit changed values are reached through the existing inherited-style
update path.

Keep targeted style reads correct by treating pending media query
evaluation as style dirtiness. Seed the style computer with the latest
viewport before resolving pending animated style, so viewport-unit
keyframes do not use stale metrics.

Share pseudo-element recomputation with inherited-style updates, so
pseudos stay current when their originating element changes only via
inherited values.

Schedule animated style updates when inherited style recomputation can
affect existing animations.

Add viewport resize coverage for media queries, inherited font metrics,
monospace font-size recascade, line-height percentages, font-relative
and pending viewport-unit animations, inherited pseudo-elements, direct
pseudo viewport dependencies, and canvas currentColor reads.
2026-05-25 11:35:35 +02:00
Aliaksandr Kalenik
399db4a213 LibWeb+WebContent: Simplify compositor context creation
CompositorHost still accepted page presentation metadata so the old
in-process compositor path could register new contexts while
constructing the LibWeb handle. With the compositor process as the only
backend, context allocation and service registration already happen
before LibWeb creates the handle.

Make CompositorHost::create_context() take only the allocated context id
and remove the private register_context() hook. Navigable no longer
computes page metadata for the host, and WebContent no longer carries a
erification-only registration override.
2026-05-25 00:45:24 +02:00
Aliaksandr Kalenik
ab54d2bd22 LibWeb+WebContent: Remove async scroll adoption deferral hook
The compositor thread used to need a way for LibWeb to postpone
adopting async scroll offsets when the thread had already presented
newer state. The compositor process implementation never defers this
path, so the hook became a hardcoded false result after the thread code
was removed.

Remove the host callback and let Navigable always consume the pending
async scroll updates from the compositor process before running
rendering-update observers.
2026-05-25 00:45:24 +02:00
Andreas Kling
ca97f68cb7 LibWeb: Normalize decoded HTML string parsing
Preserve leading BOMs when parsing already-decoded HTML strings, since
those strings do not go through the encoded byte decoder path.

Decoded markup from JS strings can also contain WTF-8 for lone surrogate
code units. Keep the common scalar UTF-8 path to a single validation and
copy, but replace surrogates before handing bytes to the Rust tokenizer.

Add text coverage for DOMParser and innerHTML string parsing, including
leading BOMs, text and attributes, lone high and low surrogates, and a
valid surrogate pair.
2026-05-24 10:14:17 +02:00
Andreas Kling
289fe72aa0 LibWeb: Keep transferred ImageBitmap data stable
Keep decoded ImageBitmap transfer bytes in a stable heap object before
handing their pixel pointer to Gfx::Bitmap. GCC can evaluate the lambda
capture that moves the ByteBuffer before the data() argument. That can
leave the bitmap backed by moved-from storage.

Taking the pointer from heap-owned storage avoids that dependency. This
does not copy pixel data. The existing crash test covers the offscreen
canvas path.
2026-05-24 10:13:23 +02:00
Aliaksandr Kalenik
6c162d8b5d LibWeb+LibWebView+WebContent: Recover after Compositor process crashes
The browser previously treated the out-of-process Compositor as fatal.

Restart the shared Compositor from the browser process, reconnect
process-backed WebContent clients, recreate compositor contexts, restore
viewport state, and ask WebContent to repaint and republish canvas and
media resources. WebContent now marks its compositor connection lost,
returns conservative values for synchronous compositor queries while
reconnecting, and drops outgoing updates until the replacement transport
arrives.

Synchronous input queries through the compositor control connection now
use fallible IPC. If the Compositor exits after the open check or before
the sync reply arrives, scroll and mouse handling report that the
Compositor did not handle the event and let the normal WebContent
fallback run.

Mouse events queued while the Compositor is unavailable now fall back to
direct WebContent dispatch. This keeps input completion in step with the
pending-event queue.

Recovery is capped at three automatic restarts. If the restart limit is
exceeded, if restart, reconnect, or context recreation fails, or if the
replacement Compositor exits during active recovery, the browser crashes
instead of switching process-backed views to a fallback path.
2026-05-24 03:35:07 +01:00
Aliaksandr Kalenik
579de06b78 LibWeb: Rename m_rendering_thread_display_list_* to m_compositor_*
"Rendering thread" is the old name for what is now called the
compositor. Rename these Navigable members to reflect the current
terminology:
2026-05-23 18:13:29 +01:00
Andreas Kling
4c03a6f5fc LibWeb: Honor transparent copy compositing in canvas
Do not skip fully transparent canvas fill and stroke styles when the
current compositing operator can still affect the destination bitmap.
TradingView uses transparent copy fills while repainting its chart
canvases, and skipping those draws left old translucent chart pixels in
place so later source-over draws accumulated on top.

Add text coverage for transparent copy replacing an existing translucent
pixel before another translucent draw.
2026-05-23 19:11:01 +02:00
Shannon Booth
637fd51595 LibWeb: Unify WebIDL C++ type generation
Represent WebIDL C++ types with a single CppType model that tracks
nullability, optional presence, and contained storage.

GC-like values now use GC::Ref/GC::Ptr directly, while containers choose
"plain", "Root", or "Conservative" container types depending on what
they contain. For example, sequence<Element> becomes a RootVector of
GC::Ref values, while sequence<SomeDictionary> becomes a
ConservativeVector only when the dictionary contains GC-like values.
This moves the generated bindings away from wrapping GC values in
GC::Root by default.

This has broad fallout as the types passed to interfaces for GC
objects changes almost fully across the board.
2026-05-23 18:26:12 +02:00
Martin Chrástek
cd3c72dfda LibWeb: Implement chardetng-based encoding detection for HTML parsing 2026-05-23 11:57:33 +02:00
Andreas Kling
56da8f01d7 LibWeb: Reject stale image decode promises
When an image source changes before a queued decode() job can attach
fetch callbacks, the current request can still be unavailable and have
no shared resource request. Treat that as the spec's current request
changed case instead of asserting while adding callbacks.

Add text coverage for changing an image source immediately after
calling decode(), matching the WPT image-decode-path-changes crash.
2026-05-23 11:36:45 +02:00
Andreas Kling
15714bade3 LibWeb: Avoid running scripts adopted during fetch
Follow the script execution model by checking the preparation-time
document before waiting for scripts to run in the node document. An
async script can be adopted into a freshly-created document while its
fetch is still pending, and that script must return without executing
when the fetch completes.

Also unblock render-blocking elements when removal disconnects them
from their browsing context, matching the render-blocking mechanism.
Add a crash test for an adopted async script whose fetch completes
after adoption.
2026-05-23 11:36:45 +02:00