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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Move HTMLStyleElement's dynamic update handling, media/type attribute
handling, and script-blocking predicate skeleton into StyleElementBase
so style elements can share that plumbing.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.