Commit graph

86 commits

Author SHA1 Message Date
Zaggy1024
57a78f2b59 LibWeb: Transfer load delayers when elements are adopted
Otherwise, the load event will block the original document until GC
runs.

Without this, media-load-task-after-adoption.html would wait for the
idle timeout to trigger a garbage collection, which could sometimes
cause the test to time out entirely.
2026-06-11 00:34:12 +02: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
Andreas Kling
43b8a8b099 LibWeb: Thread request context into ContentBlocker
Carry the initiating URL, fetch destination, initiator type, and request
mode from Fetch into LoadRequest and pass them to ContentBlocker. The
existing substring matcher still matches only the request URL, but the
blocker API now receives the context needed by source-aware backends.

Preserve that metadata for CORS preflights and connection hints, and add
coverage for resource-type mapping and blob source URL normalization.
2026-05-21 21:16:56 +02:00
Andreas Kling
8eb74bf747 LibWeb+LibWebView: Preserve crashed page URLs on crash
Load the browser-generated crash page as a synthetic response for the
URL that was active when WebContent exited. This keeps the session
history entry, response URL, and created Document aligned with the same
navigation URL, so reload targets the original page without creating a
local document for an HTTP(S) history entry.

Suppress history metadata updates from the generated page and declare
an inert rel=icon. Fallback favicon loading now follows the HTML
condition that no link with the icon keyword exists, which avoids the
credentialed /favicon.ico request from the crashed origin.
2026-05-20 20:17:45 +02:00
Andreas Kling
b849af70b8 AK+LibWeb: Reject impossible Variant visit overloads
Make Variant::visit reject typed visitor overloads that cannot be
called for any variant alternative. This catches stale visitors after a
variant payload type changes instead of falling through to a generic
overload.

Update fetch body consumers that still expected ByteBuffer after the
body payload moved to Core::ImmutableBytes.
2026-05-18 01:21:34 +02:00
Andreas Kling
318fb4f2d0 LibWeb: Preserve immutable consumed body bytes
Keep consumed response body bytes in Core::ImmutableBytes instead of
requiring a ByteBuffer. This lets responses that already arrived as
file-backed immutable data keep that representation through body
consumption, while streamed responses can still adopt their
accumulated ByteBuffer without another copy.

Update the body consumers that only inspect bytes to read from
immutable byte views. Font loading still copies at its existing
ownership boundary, where the off-thread preparation path takes a
ByteBuffer.
2026-05-18 01:21:34 +02:00
Andreas Kling
11e69d5e49 LibWeb: Support dump tools without resource loading
Allow parser dump utilities to run without installing a ResourceLoader.
Short-circuit resource fetch entry points used by links, stylesheets,
and shared resource requests when no loader is present.

Keep those failures local to headless utility use so dump-html-tree can
parse real pages without a full browser page loader or request service.
2026-05-17 15:35:56 +02:00
Andreas Kling
f1c151a17f LibWeb: Release completed link element fetches
HTMLLinkElement only needs to retain its FetchController while a linked
resource fetch is in flight, so that a later attribute change can stop
the old request. Once the current stylesheet/icon/preload fetch has
produced its response, keeping the controller alive retains FetchParams,
the Request, and the request client unnecessarily.

Clear the in-flight controller as each current linked resource fetch
finishes. Stale callbacks from older generations still return without
touching a newer controller.
2026-05-17 00:29:18 +02:00
Andreas Kling
8c59b6281d LibWeb: Ignore stale link fetch body callbacks
When a link element starts a replacement fetch, the old response body
can already have queued its consume-body task. stop_fetch() clears the
fetch algorithms for future work, so that late task re-read an empty
callback and tripped AK::Function's wrapper assertion.

Keep fetch_response_handover() tied to the algorithms object it
selected when creating the consume-body steps. Then make
HTMLLinkElement apply the HTML stale-resource check explicitly with a
fetch generation, so results from superseded link fetches return before
processing the resource.

Add a text test that replaces a stylesheet data URL and waits for the
replacement stylesheet's load event. This covers stale body callbacks
and verifies that superseded stylesheet results do not apply.
2026-05-13 20:54:10 +02:00
Yuval Carmon
eaf1078c98 LibWeb: Use stop_fetch() for overlapping HTMLLinkElement fetches
When a link element's href changes, the spec expects the callback
to check if "el contributes a script-blocking style sheet"
(step 6). This check examines current fetch state, which fails
when old fetch callbacks run after a new fetch has started.

Use FetchController::stop_fetch() instead of abort() to prevent
old fetch callbacks from executing entirely. This ensures only the
current fetch's callback runs, allowing it to correctly check
current state per spec without race conditions.
2026-05-13 04:17:24 -05:00
Andreas Kling
5cf90c0d0d LibWeb: Avoid stale delayed resource callbacks
Delayed preload and image animation callbacks can outlive the objects
they notify. Incremental sweeping makes this easier to hit because stale
callback state may be reclaimed before the delayed work runs.

Use a weak link element when firing preload load and error events, and
use a weak image style value from animated image timers instead of a raw
pointer.
2026-05-10 10:58:11 +02:00
Aliaksandr Kalenik
f8640d813a LibGfx+LibWeb: Make DecodedImageFrame a value type
DecodedImageFrame only wraps a ref-counted Bitmap and color-space
metadata. The frame object itself does not provide shared mutable
state or lifetime ownership beyond those members, so ref-counting it
adds an unnecessary layer of indirection.
2026-05-07 16:08:13 +02:00
Aliaksandr Kalenik
76c79ee522 LibGfx: Remove ImmutableBitmap
DecodedImageFrame now owns decoded bitmap pixels directly, so the
separate ImmutableBitmap wrapper no longer carries useful semantics.
Remove the class and pass decoded image frames or bitmaps at the
boundaries where pixels are actually required.

The Skia image cache now keys off DecodedImageFrame, matching the
display-list commands that paint decoded images. Video frames stay
owned by LibMedia, with the explicit YUV-to-bitmap conversion living
at HTMLVideoElement's decoded-frame entry point for canvas and WebGL
callers.
2026-05-05 14:39:17 -05:00
Aliaksandr Kalenik
40f2abb7fe LibGfx+LibWeb: Add DecodedImageFrame
Decoded image data should not continue to traffic in ImmutableBitmap now
that the bitmap wrapper is being retired. Introduce DecodedImageFrame as
the paintable decoded-image unit and store a Bitmap plus ColorSpace in
it directly.

Thread the new frame type through decoded image data, display-list
image commands, filters, canvas drawImage, patterns, WebGL texture
upload, and CSS/SVG image consumers. ImmutableBitmap remains only at
the legacy boundaries that still need it, such as HTML video snapshots
and callers that explicitly ask for a bitmap snapshot.

This keeps color-space ownership with the decoded frame while making
the expensive or legacy ImmutableBitmap path explicit at the few call
sites that still need it.
2026-05-05 14:39:17 -05:00
Andreas Kling
a538d2b160 Revert "LibWeb: Have speculative HTML parser populate the preload map"
This reverts commit b88cbb1b74.

Appears to be causing large regressions on WPT.
2026-04-30 04:55:31 +02:00
Aliaksandr Kalenik
b88cbb1b74 LibWeb: Have speculative HTML parser populate the preload map
When the regular HTML parser is blocked on an external script, the
speculative parser scans ahead and pre-fetches discoverable
sub-resources. Previously those fetches were tracked only in the
parser's own URL list and never registered in the document's preload
map, so when the regular parser later reached each element fetch()'s
consume_a_preloaded_resource() lookup found nothing and issued a
duplicate request — every parser-blocked sub-resource was fetched
twice.

issue_speculative_fetch now creates a PreloadEntry, registers it
under create_a_preload_key(request) in the document's preload map,
and supplies a processResponseConsumeBody callback that populates
the entry. The map insertion happens after fetch() starts because
fetch() runs consume_a_preloaded_resource() synchronously, so
registering the entry beforehand would short-circuit the
speculative fetch itself.

The body-handling steps (1, 2, 5 of the preload algorithm's
processResponseConsumeBody) are factored into a shared
deliver_preload_response helper used by both the speculative parser
and HTMLLinkElement::preload.
2026-04-29 15:59:22 +02:00
Aliaksandr Kalenik
70ac025eff LibWeb: Implement the speculative HTML parser
When the HTML parser blocks on a synchronous external script, run a
separate tokenizer over the unparsed input and issue speculative fetches
for the resources it finds (script src, link rel=stylesheet|preload, img
src), with <base href> tracking and template/foreign-content skipping.

Also fills in the previously-stubbed "consume a preloaded resource"
algorithm and the document's "map of preloaded resources", so that
<link rel="preload"> followed by a matching consumer deduplicates to
a single fetch.
2026-04-26 18:48:29 +02:00
Andreas Kling
3cf24872c4 LibWeb: Fix crash removing link stylesheet nested in a shadow tree
HTMLLinkElement::removed_from() used `old_root` to find the
StyleSheetList to remove the link's stylesheet from. That's wrong
when the link element lives inside a shadow tree that is itself
nested within a larger removed subtree: Node::remove() hands every
shadow-including descendant the outer subtree's root as `old_root`,
not the descendant's own containing root. So we'd look in the
document's list while the sheet was actually in the shadow root's
list, failing the did_remove VERIFY in StyleSheetList::remove_sheet.

Fix by using the sheet's own owning-root tracking. A link-owned sheet
always has exactly one owning document or shadow root (only constructed
stylesheets can be adopted, and link sheets are never constructed), so
we can just read that entry.

Also make owning_documents_or_shadow_roots() return by const reference
instead of copying the HashTable on every call, which benefits existing
iterating callers too.

Fixes a crash on https://nytimes.com/.
2026-04-23 22:37:06 +02:00
Sam Atkins
6d02296eb5 LibWeb: Pass better information to node moving/removing steps
Corresponds to:
73de9e5e1b
097be9feaa
2026-04-22 14:05:49 +01:00
Shannon Booth
fd44da6829 LibWeb/Bindings: Emit one bindings header and cpp per IDL
Previously, the LibWeb bindings generator would output multiple per
interface files like Prototype/Constructor/Namespace/GlobalMixin
depending on the contents of that IDL file.

This complicates the build system as it means that it does not know
what files will be generated without knowledge of the contents of that
IDL file.

Instead, for each IDL file only generate a single Bindings/<IDLFile>.h
and Bindings/<IDLFile>.cpp.
2026-04-21 07:36:13 +02:00
Aliaksandr Kalenik
df96b69e7a LibWeb: Replace spin_until in HTMLParser::the_end() with state machine
HTMLParser::the_end() had three spin_until calls that blocked the event
loop: step 5 (deferred scripts), step 7 (ASAP scripts), and step 8
(load event delay). This replaces them with an HTMLParserEndState state
machine that progresses asynchronously via callbacks.

The state machine has three phases matching the three spin_until calls:
- WaitingForDeferredScripts: loops executing ready deferred scripts
- WaitingForASAPScripts: waits for ASAP script lists to empty
- WaitingForLoadEventDelay: waits for nothing to delay the load event

Notification triggers re-evaluate the state machine when conditions
change: HTMLScriptElement::mark_as_ready, stylesheet unblocking in
StyleElementBase/HTMLLinkElement, did_stop_being_active_document, and
DocumentLoadEventDelayer decrements. NavigableContainer state changes
(session history readiness, content navigable cleared, lazy load flag)
also trigger re-evaluation of the load event delay check.

Key design decisions and why:

1. Microtask checkpoint in schedule_progress_check(): The old spin_until
   called perform_a_microtask_checkpoint() before checking conditions.
   This is critical because HTMLImageElement::update_the_image_data step
   8 queues a microtask that creates the DocumentLoadEventDelayer.
   Without the checkpoint, check_progress() would see zero delayers and
   complete before images start delaying the load event.

2. deferred_invoke in schedule_progress_check():
   I tried Core::Timer (0ms), queue_global_task, and synchronous calls.
   Timers caused non-deterministic ordering with the HTML event loop's
   task processing timer, leading to image layout tests failing (wrong
   subtest pass/fail patterns). Synchronous calls fired too early during
   image load processing before dimensions were set, causing 0-height
   images in layout tests. queue_global_task had task ordering issues
   with the session history traversal queue. deferred_invoke runs after
   the current callback returns but within the same event loop pump,
   giving the right balance.

3. Navigation load event guard (m_navigation_load_event_guard): During
   cross-document navigation, finalize_a_cross_document_navigation step
   2 calls set_delaying_load_events(false) before the session history
   traversal activates the new document. This creates a transient state
   where the parent's load event delay check sees the about:blank (which
   has ready_for_post_load_tasks=true) as the active document and
   completes prematurely.
2026-03-28 23:14:55 +01:00
Tim Ledbetter
91b7525e18 LibWeb: Ensure favicon URL is valid before fetching it
Previously, we would crash when attempting to fetch the favicon if
the `<base>` element had an invalid URL.
2026-02-24 15:05:31 +01:00
Sam Atkins
873680a504 LibWeb: Delay the load event until critical style subresources load
Previously, `<link rel=stylesheet>` would delay the load event until its
style sheet loaded, but not care about its subresources. `<style>`
would not delay the load event at all. Instead, each `@import` would
delay the load event.

Now, both `<style>` and `<link>` delay the load event until their style
sheet and its critical subresources have loaded or failed. This means
that CSSImportRules no longer need to delay the load event themselves,
because they do so implicitly as a critical subresource of their parent
style sheet.

This doesn't directly affect behavior, but means that any other critical
style resources we add will automatically delay the load event.

One wrinkle here is that the spec for the `<link>` element requires that
we wait for the style sheet's critical subresources *before* we create
a CSSStyleSheet, which means we don't yet know what those are.
https://html.spec.whatwg.org/multipage/semantics.html#fetching-and-processing-a-resource-from-a-link-element:critical-subresources
For now we simply ignore this, as we did before. That means we continue
to not delay the `<link>`'s load event.
2026-02-12 16:23:12 +01:00
Aliaksandr Kalenik
901cc28272 LibWeb: Reduce recompilation impact of DOM/Document.h
Remove 11 heavy includes from Document.h that were only needed for
pointer/reference types (already forward-declared in Forward.h), and
extract the nested ViewportClient interface to a standalone header.

This reduces Document.h's recompilation cascade from ~1228 files to
~717 files (42% reduction). Headers like BrowsingContext.h that were
previously transitively included see even larger improvements (from
~1228 down to ~73 dependents).
2026-02-11 20:02:28 +01:00
Sam Atkins
108ef5e088 LibWeb/HTML: Actually use charset encoding for linked style sheets
This code that used `charset` created a second `environment_encoding`
variable which shadowed the outer one, making it a no-op. Now we
actually use its value.
2026-02-06 15:04:44 +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
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
Luke Wilde
2058c05d50 LibGfx: Create Gfx::Bitmap for PaintingSurface in ImmutableBitmap 2026-01-05 15:56:15 +01:00
Tim Ledbetter
81cac9b11a LibWeb: Use a more sensible order of precedence for rel keywords
`preload` now has higher precedence than `preconnect` which in turn
takes precedence over `dns-prefetch`.
2025-12-13 10:52:25 -05:00
Tim Ledbetter
ac2334453b LibWeb: Use default fetch processing for any applicable rel keyword
Previously, the `preload`, `preconnect` and `dns-prefetch` keywords
took precedence over the others. When these keywords were present
the default fetch processing steps would not occur even when a relevant
keyword such as `stylesheet` or `icon` was present.
2025-12-13 10:52:25 -05:00
InvalidUsernameException
28ba610f32 Everywhere: Avoid large rebuilds when editing (Immutable)Bitmap headers
This reduces the number of recompiled files as follow:
- Bitmap.h: 1309 -> 101
- ImmutableBitmap.h: 1218 -> 75
2025-11-28 18:32:48 +01:00
Timothy Flynn
3dce6766a3 LibWeb: Extract some CORS and MIME Fetch helpers to their own files
An upcoming commit will migrate the contents of Headers.h/cpp to LibHTTP
for use outside of LibWeb. These CORS and MIME helpers depend on other
LibWeb facilities, however, so they cannot be moved.
2025-11-27 14:57:29 +01:00
Aliaksandr Kalenik
fa46efae48 LibWeb: Exit process_stylesheet_resource if document isn't fully active
This change is required to fix crashing in `link-re-enable-crash.html`
that is going to be introduced by switching to unbuffered fetching.
2025-11-20 06:29:13 -05:00
Luke Wilde
167de08c81 LibWeb: Remove exception throwing from Fetch
These were only here to manage OOMs, but there's not really any way to
recover from small OOMs in Fetch especially with its async nature.
2025-11-07 04:08:30 +01: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
Timothy Flynn
6057719f63 LibWeb: Use fetch to retrieve all HTMLLinkElement resources
HTMLLinkElement is the final user of Resource/ResourceClient (used for
preloads and icons). This ports these link types to use fetch according
to the spec.

Preloads were particularly goofy because they would be stored in the
ResourceLoader's ad-hoc cache. But this cache was never consulted for
organic loads, thus were never used. There is more work to be done to
use these preloads within fetch, but for now they at least are stored
in fetch's HTTP cache for re-use.
2025-11-05 18:27:36 +01:00
Timothy Flynn
c61fa1d7aa LibWeb: Pass the HTMLLinkElement fetched resource around as a ByteBuffer
Instead of passing around a large variant, which can only contain a
ByteBuffer, let's extract the ByteBuffer ahead of time and pass that
around.
2025-11-05 18:27:36 +01:00
Timothy Flynn
523433d57d LibWeb: Organize HTMLLinkElement more consistently with other IDL types
We don't typically put spec links for methods in both the .h and .cpp
(we just put them in the .cpp).

Let's also generally organize the methods in spec-order, which for
HTMLLinkElement generally goes: init fetch -> fetch -> process data.
Makes it a bit easier to scroll through the spec and the code at the
same time.
2025-11-05 18:27:36 +01: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
Lorenz A
e73e0b3c92 LibWeb: Implement CSS decode bytes algo 2025-10-16 16:44:42 +02:00
Timothy Flynn
0cae8dd712 LibWeb: Do not drop favicon resolution callbacks
Commit 77f6edaf71 tried to map the promise
returned from the ImageCodecPlugin to the same promise type used for SVG
decoding. However, `map` drops the existing resolution callbacks on the
floor.

Instead, let's keep the ImageCodecPlugin promise alone, and resolve the
returned promise explicitly.
2025-10-10 15:10:20 -04:00
Aliaksandr Kalenik
77f6edaf71 LibWeb: Support decoding SVG favicons
Adds a path that checks if blob contains SVG image before reaching for
image decoder.

Fixes logged image decoding errors on https://chatgpt.com/
2025-08-27 08:41:01 +02:00
Vaxry
040ccc3b42 LibWeb: Allow loading style sheets without a MIME type
Some websites do not specify the MIME type of style sheets, instead
using as= or just leaving it empty.

Both Chromium and Firefox do load them regardless, so let's do it too.
2025-08-17 02:34:35 +02:00
Luke Wilde
59162342e6 LibWeb: Set LinkProcessingOptions' cryptographic_nonce_metadata
Fixes external CSS being blocked on https://beatsaver.com/, where they
have a `style-src` directive set to `'self' 'nonce-[value]'`

Relates to #5643, but does not make the website load.
2025-08-07 19:26:57 +02:00
Luke Wilde
07231e74c7 LibWeb: Set Fetch destination of <link rel="stylesheet"> requests 2025-07-01 10:24:24 +12:00
Tim Ledbetter
ff3d3840ac LibWeb: Replace usages of Document::parse_url()
The spec has been updated to use `encoding_parse_url()` and
`encoding_parse_and_serialize_url()` instead.
2025-06-24 19:55:43 +02:00
Shannon Booth
e0d7278820 LibURL+LibWeb: Make URL::Origin default constructor private
Instead, porting over all users to use the newly created
Origin::create_opaque factory function. This also requires porting
over some users of Origin to avoid default construction.
2025-06-17 20:54:03 +02:00
Andreas Kling
e5d62e9915 LibWeb: Track whether HTMLLinkElement was enabled when created by parser
This information is needed by the script-blocking style sheet logic, and
its absence was causing a WPT test to crash.
2025-04-24 18:26:54 +02:00
Andreas Kling
a6dfc74e93 LibWeb: Only set prototype once for object with IDL interface
Before this change, we were going through the chain of base classes for
each IDL interface object and having them set the prototype to their
prototype.

Instead of doing that, reorder things so that we set the right prototype
immediately in Foo::initialize(), and then don't bother in all the base
class overrides.

This knocks off a ~1% profile item on Speedometer 3.
2025-04-20 18:43:11 +02:00