Commit Graph

1395 Commits

Author SHA1 Message Date
Aliaksandr Kalenik
b69ec8757f LibWeb: Store presentation callback in RenderingThread
This is preparation for future work where the rendering thread will
initiate rasterization independently and notify the UI process without
requiring coordination with the main thread.
2026-01-26 17:01:48 +01:00
Aliaksandr Kalenik
516fb5f2fe LibWeb: Make RenderingThread own display list and backing stores
This change prepares for a future where the rendering thread handles
input events directly, allowing it to trigger repainting without
waiting for the main thread. To support this, the compositor needs to
own the display list, scroll state, and backing stores rather than
receiving them per-frame from the main thread.
2026-01-26 14:53:08 +01:00
Andreas Kling
5fc276872a LibWeb: Add style invalidation for :open pseudo-class
Add proper style invalidation when the `open` attribute changes on
HTMLDetailsElement and HTMLDialogElement. The :open pseudo-class can
affect sibling selectors (e.g., `dialog:open + sibling`), so we need
full subtree + sibling invalidation.
2026-01-26 12:40:36 +01:00
Andreas Kling
37bdcc3488 LibWeb: Support MIME type sniffing for streaming HTTP responses
Previously, when loading a document, we would try to sniff the MIME
type by reading from the response body's source. However, for streaming
HTTP responses, the body source is Empty (the data comes through the
stream instead), so we had no bytes to sniff.

This caused pages like hypr.land (which sends no Content-Type header)
to be misidentified as plain text instead of HTML, since the MIME
sniffing algorithm would receive zero bytes and fall back to the
default type.

The fix captures the first bytes of the response body during fetch,
storing them on the Body object. These bytes are the "resource header"
defined by the MIME Sniffing spec - up to 1445 bytes, which is enough
to identify any MIME type the spec can detect.

Since bytes may arrive asynchronously during streaming, we use a
callback mechanism: if bytes aren't ready yet when load_document()
needs them, it registers a callback that fires once enough bytes have
been captured (or the stream ends).

The flow is:
1. FetchedDataReceiver receives network bytes, buffers them
2. When Body is created, buffered bytes are flushed to Body's sniff
   buffer, and subsequent bytes are appended as they arrive
3. Before calling load_document(), Navigable waits for sniff bytes
4. load_document() passes the bytes to MimeSniff::Resource::sniff()
2026-01-24 15:21:26 +01:00
Aliaksandr Kalenik
f63674e92d LibWeb: Fix scroll regression when pinch-to-zoom is applied
When scrolling with a visual viewport offset (from pinch-to-zoom),
scroll_viewport_by_delta() was passing m_viewport_scroll_offset + delta
to perform_a_scroll_of_the_viewport(). However, that function calculates
the scroll delta as `position - page_top()`, where page_top() includes
the visual viewport offset. This caused the effective scroll delta to be
reduced by the visual offset amount.

Fix by using the current page position (which includes the visual
offset) as the base for the delta calculation.

Regression from 0a57e1e8ac.
2026-01-23 17:52:50 +01:00
Estefania
528015b0af LibWeb/HTML: Skip fallback favicon loading for auxiliary contexts
Do not load fallback favicons from /favicon.ico for auxiliary browsing
contexts (popup windows). This matches the behavior observed in Chrome
and Firefox, and avoids unnecessary network requests that can interfere
with Content Security Policy violation reporting.

This fixes the javascript-url-navigation-evaluated-to-string-inherits-
csp.html Web Platform Test, which was failing because favicon CSP
violations were being reported before the actual test violation.
2026-01-23 10:46:28 +00:00
Zaggy1024
e6dbcccb99 LibGfx+LibMedia: Send video frames to Skia as subsampled YUV
This saves us from having our own color conversion code, which was
taking up a fair amount of time in VideoDataProvider. With this change,
we should be able to play high resolution videos without interruptions
on machines where the CPU can keep up with decoding.

In order to make this change, ImmutableBitmap is now able to be
constructed with YUV data instead of an RBG bitmap. It holds onto a
YUVData instance that stores the buffers of image data, since Skia
itself doesn't take ownership of them.

In order to support greater than 8 bits of color depth, we normalize
the 10- or 12-bit color values into a 16-bit range.
2026-01-22 19:44:36 +01:00
Reimar
26181f2958 LibWeb: Implement External interface 2026-01-22 14:56:46 +01:00
Timothy Flynn
6b91199253 LibHTTP+LibWeb: Move Infrastructure::Request::CacheMode to LibHTTP
We will need to send this enum over IPC to RequestServer to affect the
disk cache's behavior.
2026-01-22 07:05:06 -05:00
Timothy Flynn
6120b3b918 LibWeb+LibWebView+WebWorker: Enable the HTTP memory cache in workers
This is expected by WPT. For this to work, we must be able to determine
the network partition key for shared worker environments. So we now set
a top-level origin for these environments, with a FIXME to implement it
in accordance with the Client-Side Storage Partitioning spec.
2026-01-22 07:05:06 -05:00
Luke Wilde
4d882cc682 LibWeb: Don't disentangle remote port when closing MessagePort
Otherwise, the remote port will lose its transport and not receive
queued messages. The remote port will automatically close anyway when
EOF is received on the socket.

This allows https://www.tripadvisor.com/ to load, where it instantiates
a module by creating a MessageChannel, setting port1's onmessage to the
module's instantiation function, posting an undefined message on port2
and then immediately closing port2.
2026-01-22 12:44:51 +01:00
Shannon Booth
4582598d64 LibWeb: Do not broadcast storage events if storage is already empty
See: https://github.com/whatwg/html/commit/23fcf39
2026-01-21 22:27:59 +01: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
Sam Atkins
3c1d6dd38f LibWeb/HTML: Expose whether we're running in test mode 2026-01-20 06:58:16 -05:00
Jelle Raaijmakers
99923eac8d LibWeb: Add stubbed Speech API 2026-01-20 06:51:04 -05:00
Luke Wilde
babfd70ca7 LibGC: Enforce that a Cell type must declare the allocator to use
This ensures that we are explicitly declaring the allocator to use when
allocating a cell(-inheriting) type, instead of silently falling back
to size-based allocation.

Since this is done in allocate_cell, this will only be detected for
types that are actively being allocated. However, since that means
they're _not_ being allocated, that means it's safe to not declare
an allocator to use for those. For example, the base TypedArray<T>,
which is never directly allocated and only the defined specializations
are ever allocated.
2026-01-20 12:00:11 +01:00
Andreas Kling
4d92c4d71a LibJS: Skip initializing constant slots in ExecutionContext
Every function call allocates an ExecutionContext with a trailing array
of Values for registers, locals, constants, and arguments. Previously,
the constructor would initialize all slots to js_special_empty_value(),
but constant slots were then immediately overwritten by the interpreter
copying in values from the Executable before execution began.

To eliminate this redundant initialization, we rearrange the layout from
[registers | constants | locals] to [registers | locals | constants].
This groups registers and locals together at the front, allowing us to
initialize only those slots while leaving constant slots uninitialized
until they're populated with their actual values.

This reduces the per-call initialization cost from O(registers + locals
+ constants) to O(registers + locals).

Also tightens up the types involved (size_t -> u32) and adds VERIFYs to
guard against overflow when computing the combined slot counts, and to
ensure the total fits within the 29-bit operand index field.
2026-01-19 10:48:12 +01:00
Andreas Kling
07b10d7ebf LibWeb: Use FetchControllerHolder in HTMLLinkElement::preload()
The report_timing lambda was capturing `this` and reading
m_fetch_controller when invoked. This is fragile because
m_fetch_controller could be overwritten by a subsequent preload
before the first preload's callbacks run.

Use a FetchControllerHolder to bind the controller to each specific
fetch. The holder is captured by the lambda and populated after
fetch() returns, ensuring callbacks always use the correct controller.
2026-01-18 00:30:55 +01:00
Shannon Booth
8eec7d4585 LibWeb/HTML: Do not disable scripting for script based about: pages 2026-01-17 11:51:24 +00:00
Aliaksandr Kalenik
8d47c98ed3 LibWeb: Cache scroll state snapshot in ViewportPaintable
Cache the scroll state snapshot in ViewportPaintable when
refresh_scroll_state() is called.

The upcoming AccumulatedVisualContext integration requires access to
the scroll state snapshot during hit testing to transform screen
coordinates through scroll frames. Without caching, each hit test would
allocate a new snapshot (a Vector<Entry>), causing many temporary
allocations during mouse movement. Caching the snapshot eliminates this
overhead.
2026-01-15 19:50:53 +01:00
Tim Ledbetter
e16618bdd1 LibWeb: Apply textBaseline offset in Canvas measureText() 2026-01-15 10:31:23 +01:00
Tim Ledbetter
191e8218dc LibWeb: Use correct font metrics calculations in Canvas measureText() 2026-01-15 10:31:23 +01:00
Andreas Kling
cf5e0a31ee LibWeb: Avoid synchronous layout update on window.scroll(0, 0)
The coordinate (0, 0) is always inbounds, and we don't need to consult
layout results to figure out if it's within the scrollable overflow.
2026-01-14 11:46:23 +01:00
Christoffer Haglund
14ccc87190 LibWeb: Address edge case on async module load
Issue #6294 describes an edge case where the browser crash if the same
module is loaded three times in a document, but all attempts fail.

Failure scenario:
1. Module load 1 set the state to "Fetching"
2. Module load 2 registers a callback to `on_complete` since the
   current state is "Fetching"
3. Module load 1 finish with a failure, invoking the callback for load
   number 2
4. Module load 3 cause a crash. The state is neither "Fetching" or
   "ModuleScript", so we'll reset the state to "Fetching". This invokes
   the callback for module load 2 again, now with an unexpected state
   which will cause an assert violation.

Proposed fix is to remove the condition that invokes `on_complete`
immediately for successfully loaded modules only, the callback should
be invoked regardless of whether the fetch succeeded or failed.

This reveals a separate bug in HTMLScriptElement, where
`mark_as_ready()` can be invoked before
`m_steps_to_run_when_the_result_is_ready` is assigned.
This appears to be a spec bug, reported as
https://github.com/whatwg/html/issues/12073 and addressed by delaying
the callback by a task, similar to the issue was resolved for inline
scripts.
2026-01-13 18:12:38 +01:00
Shannon Booth
1106496d1c LibWeb/HTML: Ensure data: URL workers are same-origin with themselves
See: https://github.com/whatwg/html/commit/baff3f5
2026-01-13 16:59:54 +01:00
Gingeh
fbde887cc8 LibWeb: Remove API URL character encoding
See https://github.com/whatwg/html/pull/9755/
2026-01-13 13:51:32 +00:00
Shannon Booth
9eabaa6833 LibWeb/HTML: Set correct length for cross-origin wrapper functions 2026-01-13 10:11:31 +01:00
Shannon Booth
399c62933a LibWeb/HTML: Set correct name for cross-origin wrapper functions 2026-01-13 10:11:31 +01:00
Shannon Booth
d49939e230 LibWeb/HTML: Do not capture GC::Roots in cross origin function objects
JS::NativeFunction should be GC safe, so we should not be capturing
GC roots as it may cause memory leaks.
2026-01-13 10:11:31 +01:00
Jelle Raaijmakers
64f1e6e11a LibWeb: Add onanimation* event handler IDL attributes
Add these animation event handlers to GlobalEventHandlers:
- onanimationcancel
- onanimationend
- onanimationiteration
- onanimationstart

They were missing, causing `window.onanimationend = ...` style
assignments to silently fail.
2026-01-13 10:09:22 +01:00
Tim Ledbetter
ba7b0c60f0 LibWeb: Move hyperlink navigation methods to DOM::Element
This allows us to use these methods from `SVGAElement` without
inheriting  `HTMLHyperlinkElementUtils`, which we can't do for
`SVGAElement` due to a naming conflict with the `href()` method in
`SVGURIReferenceMixin`.
2026-01-13 10:05:40 +01:00
Tim Ledbetter
cf3a49cda6 LibWeb: Use href content attribute value in follow_the_hyperlink()
Previously we were using the IDL attribute value, which didn't follow
the specification.
2026-01-13 10:05:40 +01:00
Tim Ledbetter
0448731059 LibWeb: Remove unnecessary methods from HTMLHyperlinkElementUtils
These could all be implemented in terms of
`hyperlink_element_utils_element()`.
2026-01-13 10:05:40 +01:00
Tim Ledbetter
82db5c3f20 LibWeb: Parse Referrer-Policy header when creating policy container
Previously, when creating a policy container from a fetch response, the
Referrer-Policy HTTP header was not being parsed. This meant documents
loaded with a Referrer-Policy header would ignore the policy and use the
default.
2026-01-12 13:07:14 +01:00
Tim Ledbetter
1022ec3b4a LibWeb: Set referrer policy on navigation fetch requests 2026-01-12 12:47:40 +01:00
Jonathan Gamble
e090532c3e LibWeb: Remove a WTF comment that got moved outside of its context
This comment at the end of LibWeb/HTML/Focus.cpp:
```
  // What? It already doesn't have system focus, what possible
  // platform-specific conventions are there?

```
Originally followed and referred to this FIXME on line 319:
```
  // FIXME: Otherwise, apply any relevant platform-specific conventions
  // for removing system focus from topDocument's
  // browsing context, and run the focus update steps with old chain,
  // an empty list, and null respectively.
```
During the course of #7233, it was accidentally moved and attached
to a different context, following this comment below on line 325:
```
  // NOTE: The unfocusing steps do not always result in the focus
  // changing, even when applied to the currently focused
  // area of a top-level traversable. For example, if the currently
  // focused area of a top-level traversable is a
  // viewport, then it will usually keep its focus regardless until
  // another focusable area is explicitly focused
  // with the focusing steps.
```

Rather than move it to the correct place and become its git blame
villain in the process, I once more seek to remove it.
2026-01-12 11:31:08 +00:00
Jonathan Gamble
555681bdb5 LibWeb: Split PaintableWithLines from PaintableBox
No functional changes. I just hope to improve code navigation.
2026-01-12 11:00:14 +00:00
Tim Ledbetter
79a427e1ef LibWeb: Implement HTMLImageElement x() and y() getters
These attributes get the image's top left border edge  relative to the
root element's origin.

These methods ignore any transforms.
2026-01-11 00:33:08 +01:00
Psychpsyo
52781cc2fd LibWeb: Add WebXR's XRSystem 2026-01-11 00:01:24 +01:00
Shannon Booth
14634c970f LibWeb/HTML: Align OffscreenCanvas.convertToBlob to latest spec
See: https://github.com/whatwg/html/commit/903d277
2026-01-10 23:11:43 +01:00
Shannon Booth
5652975f32 LibWeb/HTML: Don't call ToString during Error serialization
This was not a specification issue, a non-string value will just
not match against any of the names and will fall back to Error,
so we should avoid the call of ToString here.
2026-01-10 21:30:04 +01:00
sideshowbarker
1b41659efd LibXML+LibWeb: Use existing HTML entities table for XML parsing too
For XHTML documents, resolve named character entities (e.g., &nbsp;)
using the HTML entity table via a getEntity SAX callback. This avoids
parsing a large embedded DTD on every document and matches the approach
used by Blink and WebKit.

This also removes the now-unused DTD infrastructure:

- Remove resolve_external_resource callback from Parser::Options
- Remove resolve_xml_resource() function and its ~60KB embedded DTD
- Remove all call sites passing the unused callback
2026-01-09 19:13:41 +00:00
Jonathan Gamble
f84e6f8acf LibWeb: Make input controls relinquish focus on outside clicks
Model "viewport focus" with Document::focused_area == nullptr.

Focus.cpp:
  When a blur occurs, remove the document entry from the old chain
  before running the focusing steps. This ensures the document atop the
  new chain is not discarded. Focus::run_focus_update_steps will then
  set focused_area to nullptr, indicating viewport focus.

EventHandler.cpp:
  Split hit testing in handle_mousedown. Use an exact hit test for
  focus/blur decisions, and a subsequent cursor hit test for
  selection/caret.
2026-01-09 18:09:09 +01:00
Jelle Raaijmakers
ae20ecf857 AK+Everywhere: Add Vector::contains(predicate) and use it
No functional changes.
2026-01-08 15:27:30 +00:00
Sam Atkins
8a0ba904b9 LibWeb/HTML: Return Promises from Window scroll methods
A version of this was added in a610639119
and reverted in 70671b4c11. The bugs
there (confusing scroll-to-position and scroll-by-delta, and not having
an execution context in some cases) have been fixed in this version.
2026-01-08 14:50:09 +00:00
Sam Atkins
0a57e1e8ac LibWeb: Clarify some scrolling-related code
A lot of our scrolling code is quite old, and doesn't match the spec,
but does use some similar names. This is quite confusing. In particular
`perform_scroll_of_viewport()` is not the same as the spec algorithm.
That algorithm is actually almost implemented in
`scroll_viewport_by_delta()`.

To clarify things, this commit makes a few changes:
- Rename perform_scroll_of_viewport() to
  perform_scroll_of_viewport_scrolling_box(). This is a better match
  for how we use this method, even if it's not actually a match for the
  algorithm. (:yakbait:)
- Move `scroll_viewport_by_delta()`'s code into a new
  `perform_a_scroll_of_the_viewport()` method, and make it take a
  position like it should. `scroll_viewport_by_delta()` now calls it
  with a calculated position.

I've avoided reusing the original `perform_scroll_of_viewport()` name to
avoid accidents.
2026-01-08 14:50:09 +00:00
CountBleck
a4051cca11 LibWeb: Serialize "auto" ByteLengths correctly in StructuredSerialize
When a "length-tracking" TypedArray/DataView is postMessage'd, the
view seen by the recipient should still be "length-tracking". However,
this wasn't the case, because the actual length was serialized, as
opposed to the JS::ByteLength, which includes the "auto" state to
signal the presence of this "length-tracking" behavior.

This fixes two subtests in...
https://wpt.live/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.html
2026-01-08 00:55:52 +01:00
CountBleck
515828d971 LibWeb: Serialize Error#cause in StructuredSerialize
The spec doesn't include this behavior (at least, not yet), but all
browsers do this, as can be seen in several subtests in
https://wpt.live/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.html
2026-01-08 00:55:52 +01:00
Andreas Kling
2ac363dcba LibGC: Only call finalize() on types that override finalize()
This dramatically cuts down on time spent in the GC's finalizer pass,
since most types don't override finalize().
2026-01-07 20:51:17 +01:00
sideshowbarker
fac81e84ba LibXML: Replace the existing XML parser with libxml2 parsing
This change replaces our LibXML parser with a new implementation that
wraps libxml2's SAX2 API.

The new Parser class uses libxml2's SAX2 callbacks to drive the existing
XML::Listener interface. That preserves backward compatibility with all
existing consumers (XMLDocumentBuilder, DOMParser, etc.).
2026-01-07 14:38:52 +01:00