Commit graph

17057 commits

Author SHA1 Message Date
Andreas Kling
ab5709edfd LibCore: Tighten EventLoop current-loop checks
Make EventLoop::current() enforce the presence of a current event loop
directly, and make EventLoop::pump() verify that it is pumping the
current thread event loop. This keeps the one-loop-per-thread invariant
explicit across the public EventLoop entry points.
2026-06-05 09:18:39 +02: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
aad293dacc LibMedia: Use direct references to main event loops
Pass direct Core::EventLoop references through media producer and
playback plumbing that posts work back to the main thread. The browser
process main loops stay alive for the process lifetime, so these paths
no longer need weak event loop references.

Update LibMedia tests to pass their stack event loop directly to the
producer helpers.
2026-06-05 09:18:39 +02:00
Andreas Kling
83b293e4f2 LibCore: Keep main event loops alive
Add an explicit initializer for process-lifetime event loops and use it
for browser, helper service, and utility main loops. This preserves weak
event loop references for cross-thread users while making main thread
loop lifetime independent of normal program teardown.
2026-06-05 09:18:39 +02:00
Andreas Kling
02b205361d LibCore: Remove nested EventLoop support
Replace the per-thread EventLoop stack with a single thread-local
pointer. Constructing an EventLoop now requires that the current thread
does not already have one, and exec() and spin_until() operate only on
that current loop instead of pushing a temporary nested loop.

LibLine was the last user that needed nested Core event loops, so the
stack allocation and pthread cleanup machinery can go away.
2026-06-05 00:09:37 +02:00
Andreas Kling
dfb2656d9c Utilities: Replace LibLine with libedit
Use libedit's readline-compatible interface for the JavaScript REPL so
line editing, history, and tab completion no longer depend on LibLine.
The REPL keeps its existing multiline input and completion behavior,
but no longer provides LibLine's live syntax highlighting.

Remove the unused LibLine dependency from the wasm utility and delete
the LibLine library from the build now that it has no remaining
consumers.
2026-06-05 00:09:37 +02:00
Ali Mohammad Pur
08221aebab LibWasm: Start execution immediately after validation
This adds a tier-up mechanism at loop edges, making it so we can
seamlessly (ish) transition between interpreted and native code so we
can start running wasm code immediately after validation while
compilation happens in the background, and switching to native code
eventually once we hit a big enough function that would benefit from
being compiled to begin with.
2026-06-05 00:08:11 +02:00
Ali Mohammad Pur
3c89c36158 LibWasm+LibWeb: Restore disk cache for compiled wasm modules
Also untangle the confusing validation layering on async compilation.
2026-06-05 00:08:11 +02:00
Sam Atkins
879fc69f89 LibWeb/CSS: Link DevTools rules to UA stylesheets
UA and user stylesheets do not have owner nodes or owner rules, so their
matched rules cannot be mapped through the generic stylesheet identifier
helper. Share the built-in UA stylesheet enumeration and map UA rules by
the matched CSSStyleSheet object, so that they stay in sync with any
future changes.
2026-06-04 20:54:33 +01:00
Sam Atkins
64e0aa8c26 LibWeb+LibDevTools: Link style rules to CSS sources
Resolve applied-rule stylesheet identities through StyleSheetsActor and
include Firefox parentStyleSheet, line, and column fields on rule forms.
Firefox can then show matched rules as stylesheet rules and open the
corresponding CSS source location from the Rules panel.
2026-06-04 20:54:33 +01:00
Sam Atkins
b2b164ebd7 LibWeb+WebContent: Report CSS rule source data
Include parser rule locations and stylesheet identities in the applied
style rule data sent to DevTools. This gives the protocol layer enough
information to map matched rules to existing stylesheet resources
without guessing from displayed rule text.
2026-06-04 20:54:33 +01:00
Sam Atkins
52e1d30404 LibWeb+LibDevTools: Report applied style rules to Firefox
Collect the style rules that apply to an inspected element and expose
them through the existing DOM node inspection path. This gives Firefox's
Rules panel real rule forms instead of the previous empty getApplied
response.
2026-06-04 20:54:33 +01:00
Sam Atkins
121105eb83 LibWebView+WebContent: Pass DOM inspection options
Extend the existing DOM node inspection request with an options payload
and carry it through the browser process, WebView, IPC, and WebContent.
This lets later DevTools requests forward Firefox's top-level flags
without changing any inspected-node behavior yet.
2026-06-04 20:54:33 +01:00
Sam Atkins
1b3296b574 LibDevTools: Avoid stale callbacks during server teardown
DevTools server callbacks can outlive the server when deferred work is
queued during connection shutdown. Capture weak pointers for those tasks
and clear socket callbacks while the server is being destroyed so later
actor cleanup cannot touch freed state.

Add protocol coverage that destroys a server with deferred actor cleanup
pending, before adding the style-rule actor path that depends on this.
2026-06-04 20:54:33 +01:00
Sam Atkins
39106f9326 LibWeb/CSS: Parse authored declarations for DevTools
Add a parser entry point that preserves authored CSS declarations for
DevTools. The Rules panel needs the original property names, shorthand
values, invalid declarations, custom properties, and !important flags
rather than only the expanded computed representation.
2026-06-04 20:54:33 +01:00
Sam Atkins
ee24561ab4 LibWeb/CSS: Store source positions on CSS rules
DevTools needs rule-level source positions to link applied style
rules back to their source sheets. The parser already tracks token
line and column information, so carry that through qualified rules
and nested declarations when creating CSSRule objects.
2026-06-04 20:54:33 +01:00
Sam Atkins
df41e7a1cf LibWeb/CSS: Move Token::Position into SourcePosition
There's nothing about this that's specific to Tokens, and moving it
makes it easier to use for other types. We'll need this for the
following commits.
2026-06-04 20:54:33 +01:00
Sam Atkins
18ac54a402 LibWeb: Invalidate styles for scoped imports
Include scoped import start and end selectors in stylesheet selector
insights, and treat scoped `@import` additions or removals as broad
stylesheet invalidation triggers. Scoped import boundaries can change
which descendants match imported rules, so add/remove invalidation
cannot rely only on the imported style rule selectors.

Add local coverage for changing an import-scope root, changing an end
boundary, replacing or removing a scoped import rule, selector-insight
tracking, and stylesheet removal invalidation.
2026-06-04 20:52:28 +01:00
Sam Atkins
85e14f5f1f LibWeb: Apply scopes from imported stylesheets
Treat a scoped `@import` rule as a scope descriptor while traversing
style-producing rules from imported stylesheets. Imported rules now
inherit an outer scope for unscoped imports and replace it when the
import itself carries scope(...).

Scope resolution was generalized to handle both CSSScopeRule and
CSSImportRule descriptors. Import-scope boundaries are matched using
the stylesheet that parsed the `@import` rule, while normal imported
selectors keep using the imported stylesheet context. This lets
implicit scopes, nested `@scope` rules, :scope, and top-level `&` behave
as the Cascade 6 model requires.
2026-06-04 20:52:28 +01:00
Sam Atkins
538dca4448 LibWeb: Parse scoped CSS import rules
Parse and store the optional `scope` clause in `@import` preludes.

WPT doesn't directly test the serialization behaviour for this, so add a
custom test for it.
2026-06-04 20:52:28 +01: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
Andreas Kling
8c7b5b4de6 LibCore: Add immediate process termination helper
Add Core::Process::terminate_immediately() as the shared primitive
for terminating a process without running exit-time destructors. Use
_exit() on POSIX and TerminateProcess() on Windows.
2026-06-04 19:20:49 +02:00
François Guerraz
f756219841 LibDNS: Reject domain name labels longer than 63 octets
A DNS label length octet is a 6-bit value, so a label can be at most 63
octets. Several code paths violated this and aborted the process:

- DomainName::from_raw() treated any length octet that was not a
  compression pointer as an ordinary label, including the reserved
  0b01/0b10 top-bit encodings, yielding labels of up to 191 octets.
- DomainName::to_raw() then VERIFY-aborted on any label longer than 63
  octets while encoding it back to the wire.
- Resolver::lookup() encoded the outgoing query with MUST(to_raw(...)),
  so even once to_raw() fails gracefully the MUST would still abort.

Together these crash RequestServer, which drives DNS for the whole
browser. When a custom resolver is configured (e.g. --dns-server), a web
page that references a host name containing a label longer than 63
characters aborts RequestServer while the query is encoded. A response
carrying a reserved-length label is also accepted by the parser and then
aborts when the name is re-encoded (for example during DNSSEC
validation).

Reject over-long labels when parsing, return an error instead of
aborting when encoding, and reject the lookup promise instead of
MUST-aborting at the query call site.
2026-06-04 17:41:09 +02:00
Sam Atkins
4ad7f06099 Revert "LibWeb: Delay load event during CSS @import fetch"
This reverts commit 1e0f6d1f7c.

Now that style sheets can block scripts, we don't need this additional
load delayer.
2026-06-04 16:39:54 +01:00
Sam Atkins
89bdc5f889 LibWeb/SVG: Apply parser-created style timing
Let SVGStyleElement delegate style updates through StyleElementBase so
parser-created inline SVG `<style>` elements update when they are popped
from the parser stack, just like HTML style elements.

This lets SVG style imports participate in script-blocking stylesheet
checks while keeping dynamic text, type, and media changes from
re-blocking parser scripts.
2026-06-04 16:39:54 +01:00
Sam Atkins
5d566040d6 LibWeb/DOM: Evaluate style media for script blocking
Evaluate the associated stylesheet's media queries when a parser-created
`<style>` sheet is created, and re-evaluate them when the media
attribute changes.

This lets HTMLStyleElement::contributes_a_script_blocking_style_sheet()
honor the media clause from the HTML script-blocking rules. A
still-loading parser-created style is removed from the script-blocking
set as soon as its media no longer matches.
2026-06-04 16:39:54 +01: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
Sam Atkins
5cc0e1408a LibWeb/CSS: Treat non-matching @import supports() as loaded
Mark `@import` rules whose supports() condition is false as loaded
before returning from fetch(). These rules do not fetch a stylesheet,
but they still participate as critical subresources of the parent
sheet.

Leaving them Unloaded kept parser-created `<style>` blocks waiting for
critical subresources that can never finish, which blocked following
parser scripts forever.
2026-06-04 16:39:54 +01:00
Callum Law
4730493667 LibWeb: Apply body attribute link colors as presentational hints
Previously we overrode the resolved values of the `activetext`,
`linktext`, and `visitedtext` system colors based on the values of the
body's `alink`, `link`, and `vlink` attributes respectively.

This was incorrect and the spec instead expects us to apply these to the
relevant link elements as presentational hints while leaving those
colors untouched for other users.
2026-06-04 16:14:05 +02:00
Callum Law
843bd808cf LibWeb: Move `:visited: matching into helper method
And add spec text to explain why it never does.

We will be checking whether the `:visited` pseudo class matches in more
places in a future commit so this avoids duplicating FIXMEs.
2026-06-04 16:14:05 +02:00
Callum Law
b1e3306a24 LibWeb: Remove "attempted pseudo-class match" machinery
This is no longer used anywhere after fa57975
2026-06-04 16:14:05 +02:00
Callum Law
65134fc5da LibWeb: Remove dead code around resolving accent-color <system-color>s
While the spec says that `accentcolor` and `accentcolortext` resolve
relative to the `accent-color` property this isn't implemented by any
other browsers.

This effectively reverts d04b745 but doesn't change behavior since that
was already done in 92897a1.
2026-06-04 16:14:05 +02:00
Tim Ledbetter
9de60cd4f9 LibWeb: Apply the text-anchor property to SVG textPath offset 2026-06-04 16:01:56 +02:00
Tim Ledbetter
ad7105b570 LibGfx+LibWeb: Implement SVGTextPathElement.startOffset 2026-06-04 16:01:56 +02:00
Tim Ledbetter
d92f93f34e LibWeb: Skip non-rendered text nodes in SVG textPath layout 2026-06-04 16:01:56 +02:00
Tim Ledbetter
260064deef LibWeb: Fall back to xlink:href when resolving SVGTextPathElement path 2026-06-04 16:01:56 +02:00
François Guerraz
c984ce2429 LibWeb/SVG: Fix crash parsing a coordinate sequence that ends mid-token
AttributeParser::parse_coordinate_sequence() appended the result of
parse_coordinate() to the sequence even when parsing had failed on a
non-first iteration: its error branch was missing the `break` that the
sibling parse_coordinate_pair_sequence() has. Calling release_value() on
the errored ErrorOr then trips a VERIFY and aborts the process.

A path such as `<path d="H1,,">` reaches this: after the first
coordinate the trailing comma leaves match_comma_whitespace() true, the
following parse_coordinate() fails, and the loop falls through to
release the error.

Break out of the loop on a non-first error, matching the sibling
function.
2026-06-04 13:36:16 +01:00
François Guerraz
be4173af81 LibWasm: Validate a tag's type index before dereferencing it
The throw and try_table validators looked up the tag referenced by the
instruction, then indexed m_context.types with the tag's type index
without checking it was in range. validate(TagIndex) only validates the
tag index itself, and the tag section is validated after the code
section, so a module whose tag carries an out-of-range type index
reached the unchecked m_context.types[...] access and tripped a Vector
bounds assertion during validation.

Any WebAssembly.compile() of such a module aborts the WebContent
process.

Validate the tag's type index before using it, the same check
validate(TagType) already performs.
2026-06-04 13:54:58 +02: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
716ab93c1a LibWasm: Block while waiting for Cranelift compilation
The background Cranelift pass can race with the first call into a
module. In that case ensure_cranelift_compiled() waited by repeatedly
polling the module state and burning CPU until the compiler thread
finished.

Keep the atomic state for the completed fast path, but pair the
compiling state with a condition variable. Completion now broadcasts
while holding the associated mutex, so waiting callers sleep and cannot
miss the transition to finished.
2026-06-04 00:15:26 +02:00
Timothy Flynn
7fc71e563b LibWebView+UI: Reduce boilerplate to update the bookmarks bar display
We currently use LibWebView's Application as the entry point to learn
about the bookmarks bar being shown/hidden, and propagate that through
virtual methods. At the time this was added, AppKit's Tab window and
Qt's BrowserWindow did not have a settings observer. They do now, so
let's skip a couple of middle-men.

For AppKit, we change the settings observer to just (weakly) store the
Tab instance so that we don't have to add callback functions for each
setting.
2026-06-03 18:14:12 -04:00
Timothy Flynn
83105b8349 LibWebView+UI/Qt: Move the show menu bar setting to LibWebView settings 2026-06-03 18:14:12 -04:00
Timothy Flynn
80554dc914 LibWebView+UI/Qt: Move the vertical tab width to LibWebView settings
Let's store this alongside all other vertical tab settings.
2026-06-03 18:14:12 -04:00
Andreas Kling
ff13ac2b79 LibWeb: Avoid copying ASF argument component values
Parse arbitrary substitution function arguments as spans into the
existing component value list. This avoids copying each argument into a
new vector for var(), attr(), env(), if(), and inherit() parsing.

Expose a span-returning declaration-value parser that shares the same
walker as the existing vector-returning API, so the argument parser does
not duplicate declaration-value grammar logic. Substitution output still
uses owned vectors, and the unresolved Typed OM reifier now consumes
spans too.
2026-06-03 22:28:54 +02:00
Andreas Kling
70e82d39ed LibWeb: Store unresolved style values as text
Store the source text for unresolved CSS values instead of retaining
the full parsed component value tree. Values that need the component
tree now parse it on demand from the stored text.

This preserves equality, tokenization, variable substitution, and Typed
OM reification. Custom properties keep their original source text.
Unresolved values synthesized from component values store serialized
text.
2026-06-03 22:28:54 +02:00
Timothy Flynn
e18cd253f0 UI/Qt: Add an advanced setting to enable server-side decorations
This adds a setting to disable our custom window decorations and let the
system's window server paint the window instead.
2026-06-03 17:30:26 +01:00
Thiyagesh Venkatesan
5b2dc0dabc LibWeb: Throw from SourceBuffer::buffered() after removing SourceBuffer
Make SourceBuffer::buffered() throw InvalidStateError when the
SourceBuffer is no longer present in its parent MediaSource.

This matches the existing removed-SourceBuffer checks in other methods
in the file.

Also change the return type for SourceBuffer::buffered() to
WebIDL::ExceptionOr so the getter can return the error.
2026-06-03 11:15:45 -05:00