Propagate the CORS-cross-origin state from image fetch responses through
SharedResourceRequest, ImageRequest, and the available image cache.
Use that state when drawing HTML images to canvas so cross-origin image
data taints the canvas correctly.
Instead of comparing the current time to the duration, the playback
manager now has an explicit Ended state that jumps to the duration. The
element simply reacts to that to trigger the ended event and attribute,
along with all the other steps involved.
This moves the ended event to fire after the seeked event, which
matches other browsers' behavior. The spec doesn't explicitly say which
order they should fire in.
Since the queued task callback is already capturing the media element
weakly, we may as well directly use that in the steps that need to
interact with the element, which is the majority of them.
Also, root the element in the callback. This ensures that any queued
tasks will fire events before the element gets collected.
When scrubbing, make the timeline progress match exactly to the cursor
position. Also, set the timestamp to match that progress. Both are not
allowed to change until the scrub completes.
This makes the UI stable while scrubbing after the end of the media
data in subsequent commits that jump the time to the duration at EOS.
Whenever the controls' timeline is clicked, it pauses the media element
before seeking, then play()s on mouseup. However, the play() returns a
promise that resolves when the media actually becomes playable at the
new position. If that takes long enough that a second click pauses the
element again, then that play() promise gets rejected, and an unhandled
rejection is logged.
To prevent that, mark all play promises as handled to silence them.
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.
Move owned ArrayBuffer and SharedArrayBuffer data blocks into the
ArrayBuffer heap partition. Keep unowned and host storage explicit, so
Wasm memory and external LibWeb buffers stay outside this partition.
Introduce DataBlock::OwnedBackingStore as the LibJS-owned byte storage
representation. Expose byte spans instead of a ByteBuffer object, giving
ArrayBuffer one allocation boundary that can later grow toward guarded
or caged storage.
Let callers that need ByteBuffer data copy from backing-store bytes.
Keep TransferArrayBuffer zero-copy by moving the DataBlock directly
instead of materializing a ByteBuffer in between.
Update the Wasm typed-array test helper to compare viewed byte ranges
after ArrayBuffer stops exposing ByteBuffer identity.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
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.
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.
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.
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.
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.
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.