Commit graph

2067 commits

Author SHA1 Message Date
Tim Ledbetter
de0b733bed LibWeb: Implement suffering from bad input for input elements
Email field support is left unimplemented because we don't have a way
to convert email addresses to punycode.
2026-06-08 19:28:37 +02:00
Tim Ledbetter
525ce459fc LibWeb: Avoid stale DataTransferItem access after clearing data
Previously, clearing a DataTransfer's data removed entries from the
drag data store without updating the associated `DataTransferItem`
objects. An item obtained beforehand kept an index that no longer
referenced a valid entry, so reading its kind or type accessed an
out of bounds element of the now-empty list and crashed. We now keep
the item objects in sync when clearing data, placing any stale ones
into the disabled mode.
2026-06-08 13:40:22 +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
Andreas Kling
42a6253d64 LibWeb: Avoid idle callback churn in hidden documents
Do not start idle periods for hidden documents. This prevents
background tabs from promoting chained requestIdleCallback work into
new idle tasks immediately.

Also avoid queueing a follow-up idle task after the last runnable idle
callback has been consumed.

This fixes an issue where opening GitHub links in background tabs would
cause their WebContent processes to churn 100% CPU until you open them.
2026-06-08 01:56:11 +02:00
Andreas Kling
5c169091de LibWeb: Propagate outerText replacement exceptions
Propagate exceptions from the outerText replace step instead of assuming
that replacement always succeeds. Replacing the document element with a
rendered text fragment can legitimately fail with a DOMException.

Add a reduced crash test for setting outerText on documentElement.
2026-06-08 01:04:08 +02:00
Andreas Kling
613a04e4df LibWeb: Skip styleless nodes for rendered text
Rendered text collection needs computed style only for nodes that are
being rendered. A stale layout node can remain without style or a styled
parent, so treat that as not rendered instead of asserting while reading
innerText or outerText.

Add reduced crash coverage for reading outerText from a style element
after disabling and adopting it into another document.
2026-06-08 01:04:08 +02:00
Andreas Kling
57bf4bec64 LibWeb: Ignore invalid body background hints
The body background attribute can fail to produce an image style
value. Applying presentational hints should ignore the attribute in
that case instead of asserting.

Add reduced crash coverage for updating style after an invalid body
background hint is adopted into the active document.
2026-06-08 01:04:08 +02:00
Andreas Kling
485ca67164 LibWeb: Skip inactive media element tasks
Media element tasks are queued as element tasks. The element can move
to another document before the queued task runs.

Abort the task if the media element's current document is no longer
fully active. This preserves the media resource fetch invariant.

Add reduced crash coverage for adoption into an inactive document.
2026-06-08 01:04:08 +02:00
Andreas Kling
fe51d6ce5d LibWeb: Handle blurring nodes without a browsing context
DOMParser-created documents do not have a browsing context, but elements
created in them can still be passed to the HTML blur() steps. The
unfocusing steps only have a top-level focus chain when the old target
finds itself in a browsing context, so return early when there is none.

Add reduced crash coverage for blurring a body element created in a
DOMParser document.
2026-06-08 01:04:08 +02:00
Andreas Kling
7afc862bc0 LibWeb: Handle BarProp without a top-level context
BarProp.visible first handles a null browsing context, but the
top-level browsing context lookup can also return null when the
relevant document is no longer fully active. Return true in that
case instead of dereferencing the null result.

Add a reduced Crash/HTML test from the domato fuzz-00063 sanitizer
finding that reads menubar.visible through an inactive frame window.
2026-06-08 01:04:08 +02:00
Andreas Kling
e9b8c3f7c6 LibWeb: Skip COOP access reporting for inactive documents
WindowProxy property access can reach COOP access reporting after iframe
removal. That leaves the accessed active document not fully active.

The reporting algorithm only applies to fully active documents. Return
early for inactive documents instead of asserting. Add a crash test for
accessing a window proxy after iframe removal.
2026-06-08 01:04:08 +02:00
Andreas Kling
9340d2d1a3 LibWeb: Make layout nodes refcounted
Move the layout tree from GC allocation to refcounted ownership so
removed layout and paint subtrees are destroyed synchronously instead
of waiting for the next GC sweep. This dramatically reduces GC memory
usage peaks after layout tree churn and makes it easier for memory use
to fall back after large document updates.

Update layout factories, tree traversal, SVG layout node creation,
paintable back-pointers, and pseudo-element layout links to use RefPtr
ownership.

Make display: contents follow the same shape as Blink and WebKit: the
element itself does not create a layout node, and its children are
flattened into the nearest layout parent. Wrap direct non-whitespace
text in an anonymous inline node when the boxless element contributes
inherited style to that text.

Use an internal inline wrapper for display: contents pseudo-elements
so generated content can still participate in layout, painting, hit
testing, and pseudo-element queries. Keep CSSOM reporting the computed
display value from the pseudo style, not the internal wrapper.

Remove the retained out-of-tree layout node list and its testing hook,
since the flattened model does not need a side owner for boxless
elements. Add coverage for inherited text style, dynamic insertion
order, pseudo-element hit testing, and computed style queries.
2026-06-07 20:52:49 +02:00
Zaggy1024
e24540330e LibWeb: Enable playback rates other than 1.0
The allowed range for now is 0.0-64.0. If that turns out to be too wide
a range, we'll reduce it.

Chromium and Firefox are more restrictive, only allowing between a
minimum non-zero number and 16.0. They also allow 0.0.
2026-06-06 19:58:17 -05:00
Zaggy1024
7ddbc2d7dd LibWeb+LibMedia: Wire up setting the pipeline's playback rate
However, the playback rate is still limited to 1.0 at the element,
because audio stretching is not yet implemented.
2026-06-06 19:58:17 -05:00
Andreas Kling
7c06c3fd14 LibWeb: Make computed style data refcounted
Move ComputedProperties and CascadedProperties out of the GC. They no
longer contain strong references to GC-managed data.

Keep computed styles alive from DOM elements and animation updates with
RefPtr. Pass style into layout constructors by reference, since layout
only copies the values it needs while building nodes.

Use GC::Weak for cascade source links, so entries no longer keep the
style declaration or shadow root alive.
2026-06-06 23:29:48 +02:00
Andreas Kling
222c1f7044 LibWeb: Move CSS image loading state to Document
Move the SharedResourceRequest, animation timer, and current frame
state out of ImageStyleValue and into a Document-owned table keyed
by resolved image URL. ImageStyleValue now keeps only URL metadata
and its client list, so image style values no longer need to trace
GC edges themselves.

Thread the Document through AbstractImageStyleValue APIs that need
decoded image data. CSS image fetches snapshot the stylesheet base URL,
referrer behavior, and origin-clean state instead of retaining the
stylesheet.

Remember each client's registered resolved URL when unregistering. This
keeps a later document base change from leaving an animated image
resource alive.

Add text coverage for inline relative image base URLs, stylesheet
referrers, imported stylesheet origin-clean behavior, inline @import
initiator type, and unregistering an animated background image after a
base element change.
2026-06-06 23:29:48 +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
Aliaksandr Kalenik
852c7a10f3 LibWeb: Let image paint callers own clipping
DecodedImageData::paint() used to take both a destination and a
clip rectangle even though most callers passed the same value. SVG
image painting used that API to wrap every nested SVG display list in
save/add-clip/restore, which put an unbounded command in front of
the bounded nested-list command and made offscreen SVG image content
harder to cull.

Move clipping to ImagePaintable, where the object-fit destination can
be compared with the replaced element box. CSS image and marker
painting continue to draw into their destination rect, while repeated
background images keep their explicit tile clip. The scaled decoded
image display-list command now stores only its destination rect and
uses that as its bounds; playback still clips decoded images to that
rect so bitmap rendering stays unchanged.
2026-06-06 13:23:21 +01:00
Andreas Kling
570ea59277 LibWeb: Run same-document commit handlers during entry update
Move Navigation API commit handler completion into a helper. This lets
same-document entry updates run currententrychange before the intercept
handlers. Keep same-document traversals from aborting the ongoing
NavigateEvent before that entry update runs.

Add text coverage for intercepted and non-intercepted same-document
history traversals updating the Navigation API current entry before
navigatesuccess.
2026-06-06 11:34:50 +02:00
Andreas Kling
3ec9733efe LibWeb: Resume intercepted history traversals
When a traverse navigate event is intercepted, queue the resume step
specified by the Navigation API. This keeps intercepted traversals from
stopping at URL update time.

Do not resume that queued step if the intercepted NavigateEvent was
aborted or replaced by a newer ongoing event before it runs. Add tests
for the basic intercepted traverse case and the superseded intercepted
traverse case.
2026-06-06 11:34:50 +02:00
Andreas Kling
6ecfcd3e68 LibWeb+LibJS: Cache decoded JS bytecode sidecars
Add a ref-counted decoded bytecode cache backing so bytecode cache
materialization can create fresh script or module records from a shared
decoded sidecar without passing around one-shot raw blob ownership.

Keep that backing in ExecutableBacking for records materialized from
bytecode cache sidecars, so the immutable decoded data stays alive for
as long as the installed record needs it.

Cover the shared backing path with a bytecode-cache test that
materializes and runs two scripts from one decoded backing.
2026-06-06 09:15:09 +02:00
Andreas Kling
72720bc229 LibWeb: Preserve JS bytecode in memory cache
Store JavaScript bytecode side data in the WebContent HTTP memory
cache and replay it when serving cached responses. Also update an
already-complete memory-cache entry when asynchronous bytecode cache
generation finishes, so the first source-only response does not keep
shadowing the disk-cache sidecar during same-process navigations.

Keep the HTTP memory-cache backfill keyed with the request headers that
populated the memory-cache entry, so Vary responses still receive their
generated bytecode sidecar.

Add LibHTTP coverage for round-tripping bytecode side data through a
memory-cache entry, attaching it after the response body has already
been cached, and matching Vary headers during updates. Add LibWeb
coverage for preserving the memory-cache request headers when cloning
responses.
2026-06-06 09:15:09 +02:00
Andreas Kling
ec421d7fa4 LibWeb+LibJS: Validate bytecode cache blobs off-thread
Warm cache hits used to validate bytecode cache blobs on the main
thread. Route script and module sidecars through a worker step that
decodes and validates the cache blob, then returns the validated blob
for main-thread materialization.

Keep the source bytes mmap-backed and avoid decoding the full source on
cache hits. The main thread still computes the UTF-16 source length so
validation can reject stale blobs before materialization.

Remove the decoded source length getter now that sidecar validation uses
the explicit validation API instead.
2026-06-05 21:55:55 +02:00
Andreas Kling
bf81464904 LibWeb+LibJS: Remove rust_pipeline_available
The Rust pipeline is always available now, so the getter only wrapped
code that always ran. Remove it and make the JavaScript fetch paths use
the off-thread Rust pipeline directly.

This also removes the unreachable synchronous fallback branches from the
classic script and module fetch paths.
2026-06-05 21:55:55 +02:00
Shannon Booth
13bae036d8 LibWeb: Do not refer to removed C++ DAFSA code generator 2026-06-05 20:23:24 +02:00
Zaggy1024
0ce19a19ea LibWeb: Leave input elements' text node contents unchanged while typing
Replacing the text node's contents with the normalized value after each
keystroke made it impossible to type some inputs. For example, `1e`
would cause the text node to be emptied, making it impossible to type
`1e2`. Also, `time`, `date`, and other time-related input types had no
intermediate valid values, so it was genuinely impossible to type in
them.

Additionally, typed numbers weren't being parsed as floats before
normalization, so even just typing `1.` would clear the text node, so
it was impossible to type a fractional number.
2026-06-05 12:49:24 +02:00
Zaggy1024
e6664213ac LibWeb: Fall back to TextInputBox for unsupported input types
This isn't strictly correct as it stands currently, since the size
attribute isn't supposed to affect type="time" and others, but those
types currently end up with zero width instead.

Size could probably be applied through shadow DOM style, and the input
layout box would simply allow content sizing.
2026-06-05 12:49:24 +02:00
Callum Law
f28e7120ea LibWeb: Ensure that shadow roots have hosts before appending children
This change gives each shadow root its host before appending its
children, and asserts that a root has no children when it's assigned to
a host. This ensures the children inherit the correct connectedness.

Otherwise, without this change, the user-agent shadow trees for color
and file inputs append their children before the shadow root is given
a host which, if the input element has already been inserted, means the
children stay marked disconnected despite being present in the rendered
tree. Disconnected nodes then skip layout invalidations they should
trigger.

Fixes a crash when submitting a prompt on https://chatgpt.com
2026-06-05 18:08:21 +09:00
Andreas Kling
789d7cba48 LibWeb: Use direct references to main event loops
Post off-thread font, script, and DNS completion work back to direct
Core::EventLoop references. These callbacks target the process main
loop, which is intentionally kept alive for the lifetime of the
process.
2026-06-05 09:18:39 +02:00
Andreas Kling
164ed80244 Meta: Enable exit-time destructor warnings for libraries
Enable -Wexit-time-destructors for all in-tree library targets and
update process-lifetime library statics so they no longer register
exit-time destructors. Long-lived caches, lookup tables, singleton
registries, and generated constants now use NeverDestroyed or leaked
references where the data is intended to live until process exit.

Update LibWeb, LibLine, and the binding generators so regenerated
sources follow the same rule instead of reintroducing destructed
statics.
2026-06-04 19:20:49 +02:00
Sam Atkins
bb4f8a6621 LibWeb: Track parser-created style sheets
Create parser-blocking style sheets when parser-created `<style>`
elements are popped from the stack of open elements, and ignore dynamic
style updates while those elements are still open in the parser.

Make the shared style-element script-blocking predicate describe the
active style sheet instance. Stale script-blocking entries are removed
when that style sheet is replaced or removed.
2026-06-04 16:39:54 +01:00
Sam Atkins
c1953f93c7 LibWeb: Move style element hooks to StyleElementBase
Move HTMLStyleElement's dynamic update handling, media/type attribute
handling, and script-blocking predicate skeleton into StyleElementBase
so style elements can share that plumbing.
2026-06-04 16:39:54 +01:00
sideshowbarker
898be8badb LibWeb: Cancel the async-scroll hover update when the document changes
Problem: A document loaded into a navigable just after a previous
document in that navigable had been async-scrolling could receive hover
and mouseover/mouseout boundary events which nothing in that document
triggered. In our CI, that manifested as an intermittent flake/failure
of the async-scrolling/hover-updates-after-async-scroll.html test —
whose first mouseover count came up one short: A leftover refresh had
moved hover onto the target before the test added its listeners.

Cause: A navigable tears down a document’s input state implicitly: Its
hover target and mousedown target are GC::Weak references that null
themselves once the document is collected. The post-scroll hover refresh
wasn’t getting that automatic teardown. It runs off a Core::Timer that’s
stopped when the navigable is destroyed — but was *not* being stopped
when the navigable swaps in a new active document. So, a scroll in one
document left a refresh that fired against the next.

Fix: Cancel the pending refresh when the navigable’s active document
changes — the same boundary at which the weak references null. That
gives the timer the same teardown the rest of the input state already
has — with no per-document tracking state.
2026-06-04 11:06:14 +02:00
Zaggy1024
effb3fad3c LibWeb: Stop rounding to the nearest integer when dragging range inputs
set_value_as_number() already snaps the value to the nearest step, the
round and FIXME here were unnecessary.
2026-06-03 21:26:53 -05:00
Zaggy1024
10ba2ddbb7 LibWeb: Access range inputs' mouse events' clientX by casting
This is a bit more legible, and should be a bit more efficient than a
property lookup by name as well.
2026-06-03 21:26:53 -05:00
Andreas Kling
afb0fa2413 LibJS: Hash encoded source identity in bytecode cache
Switch bytecode cache source identity from decoded UTF-16 source text to
the original encoded response bytes plus the effective source encoding.
Store the decoded source length in the cache blob header so warm loads
can build lazy SourceCode objects without decoding the source before
checking the sidecar.

This removes the main-thread decoded_source_text_info pass from valid
warm-cache script and module loads. The source is only decoded on cache
miss, or when a rejected sidecar falls back to source compilation.
2026-06-03 14:11:23 +02:00
aplefull
52f45aef4e LibWeb+LibJS: Don't crash when serializing deeply nested values
Deeply nested structures passed to JSON.stringify or structuredClone
would cause a lot of recursion, eventually causing a crash.

We now throw an InternalError instead, same as other browser engines.
2026-06-03 13:00:01 +01:00
Andreas Kling
d9d8c5ce89 LibWeb: Allow Option-generated text insertion
Track whether a keydown should perform text insertion separately from
the delivered code point. Native frontends and text-oriented test paths
can now mark events that came from text input, while shortcut-style key
events keep Alt-modified default insertion suppressed.

This lets macOS Option-generated text such as Option+A and Option+Space
insert into editable controls without making plain Alt shortcuts insert
their base character. Add coverage for Alt text, Ctrl+Alt text,
separator text, Ctrl-only shortcuts, and Alt shortcuts.
2026-06-03 13:51:32 +02:00
Callum Law
31d8b68e73 LibWeb: Guard tasks against playback manager being cleared
The (invocation of) `on_unsupported_format_error` was already guarded
against this but it was possible for us to have moved on to the next
candidate in the interim.

Fixes a crash on https://chatgpt.com
2026-06-02 22:22:22 -05:00
Aliaksandr Kalenik
5595efd46b LibWeb: Avoid display list rebuilds for VV changes
Visual viewport scroll and pinch zoom used to invalidate the full
accumulated visual context tree and display list, even though those
changes only modify the root visual viewport transform. That forced a
full display list rerecord before sending updated compositor state.

Patch the reserved visual viewport AVC node in place instead.
VisualViewport marks the tree for compositor update without
invalidating the display list, and Navigable sends the replacement tree
through the new IPC path before updating scroll state.
2026-06-03 02:12:39 +01:00
Aliaksandr Kalenik
78cda6a97e LibWeb: Reserve visual viewport AVC root
The accumulated visual context tree used index 0 as a null sentinel, so
visual viewport transforms were only represented by adding a normal
transform node when the transform was non-identity. That made callers
treat index 0 as a special no-context value and kept the tree shape
dependent on the visual viewport state.

Reserve index 0 as the visual viewport transform node instead. AVC
traversal, display-list replay, hit testing, debug dumping, and root
paint state now treat that node as a real root. Rebaseline the affected
display-list and async-scrolling text expectations so the explicit root
node appears in AVC dumps.
2026-06-03 02:12:39 +01:00
Andreas Kling
60847b9937 LibWeb: Respect page client focus for navigables
Make navigable focus depend on whether the page client currently has
system focus. WebContent already receives focus changes from the UI
process, but LibWeb did not consult that state when deciding whether the
top-level traversable was focused.

Repaint the text caret when WebContent focus changes so a focused text
control stops showing an active caret as soon as browser chrome takes
focus, and resets the blink cycle when page focus returns.
2026-06-03 02:53:37 +02:00
Andreas Kling
6f616ae9a9 LibGfx: Remove TinyVG image decoding
Remove the TinyVG decoder now that the Qt chrome no longer depends on
TVG resources. Drop the decoder registration, MIME and supported image
type entries, fuzzer target, decoder tests, and TinyVG test inputs.
2026-05-31 19:20:59 +02:00
Callum Law
a79ec6c228 LibWeb: Consolidate parsing of canvas colors
We also resolve font-relative lengths based on the canvas' font, see the
AD-HOC comment in AbstractCanvasMixin.cpp
2026-05-31 14:09:51 +02:00
Callum Law
03e2fd1e77 LibWeb: Absolutize relative filter lengths using canvas font 2026-05-31 14:09:51 +02:00
Callum Law
2c71153f79 LibWeb: Absolutize relative letterSpacing lengths using canvas font
We now use the LRC generated based on the canvas' font where previously
we used the canvas element's, if it was connected, otherwise the
document's.

We also move this method from being static to a member of
`CanvasTextDrawingStyles` since it will eventually be used by
`OffscreenCanvasRenderingContext2D` (and needs access to member methods)
2026-05-31 14:09:51 +02:00
Callum Law
385b2ee753 LibWeb: Add method to get computation context based on canvas font
This is used for absolutizing the other canvas values (e.g.
letterSpacing, fillStyle, strokeStyle, etc)
2026-05-31 14:09:51 +02:00
Callum Law
39ab556cd0 LibWeb: Remove unnecessary FIXMEs in canvas_font_computation_context 2026-05-31 14:09:51 +02:00
Callum Law
5bd4e2d6f3 LibWeb: Allow calculated values for canvas letterSpacing 2026-05-31 14:09:51 +02:00
Callum Law
3e1f0f3b00 LibWeb: Align AbstractCanvasMixin method names with implementers
This avoids us having to define extra wrappers.

The exceptions to this are `mutable_path` and `my_realm` which are
defined in classes which don't inherit from `AbstractCanvasMixin` and
thus still require a wrapper.
2026-05-31 14:09:51 +02:00