Produce JS-visible string results as UTF-16 at their source, including
numeric formatting, BigInt and BigFraction formatting, URI encoding,
console formatting, parser errors, regular expression errors, Intl and
Temporal records, LibUnicode locale boundaries, and LibWeb bindings.
Handle fractional radix formatting through the UTF-16 builder view.
Previously we assumed that if the calculation had been simplified to a
single `NumericCalculationNode` that we could resolve it - this isn't
the case if we have a percentage that should be resolved to a different
type.
Fixes#10209
UnresolvedStyleValue::create() serialized the component values into a
comparison string unconditionally, but the result is only used when the
caller supplied separate original source text. On the common path that
serialization (including float formatting of every numeric token) was
computed and immediately discarded.
Move the serialization into the branch that actually uses it. This is
hot during var() substitution, where many intermediate
UnresolvedStyleValues are created and never compared.
Previously, math function serialization assumed the calculation tree
root was a numeric value or a calc-operator node, and otherwise emitted
the root's name followed by its comma-separated children.
A non-math function node such as `sibling-index()` or `anchor()` has no
children, so a `calc()` whose entire contents was such a function
serialized to an empty "calc()". We now serialize the function directly
instead.
Previously animation ownership was a messy split between
`AnimatedBitmapDecodedImageData` and the consumers (i.e.
`ImageStyleValueResource`, `HTMLImageElement`, and `SVGImageElement`)
with `AnimatedBitmapDecodedImageData` owning the frames and a current
frame index, and the consumers owning the rest of the state (e.g. loop
count, timers to drive the animation forward, their own current index).
This had a couple of main issues:
- While `AnimatedDecodedImageData` partially synchronized animations by
dropping unexpected advancement notifications, this didn't apply to
other animation state which meant, for instance, that a later started
consumer could drive the animation of an earlier one past the max
loop count (albeit without invalidating the earlier consumer).
- Multiple consumers didn't share frame timings, meaning animations
could be up to a full frame out of sync visually.
- Animations were paused depending on whether there were any consumers,
this is different to the behavior in other browsers (where they
continue regardless of whether there are any consumers).
- It was an overgeneralization of how animations need to work - only
`AnimatedBitmapDecodedImageData` works with an indexed frame model,
with animated SVGs (although not yet implemented) relying on their
internal event loop to be driven forward.
Given the above the new approach implemented in this commit is:
- The API for `DecodedImageData` is animation system agnostic, only
exposing `default_frame`, `current_frame`, and `restart_animation`
methods not reliant on providing a specific frame index.
- `AnimatedBitmapDecodedImageData` owns its own timer, loop count,
etc. The animation starts when the first consumer registers and ends
when the document is hidden or becomes inactive (or completes in the
case of finite animations).
- Consumers are invalidated by `AnimatedBitmapDecodedImageData` when
required.
Tests have been added for:
- Animations being paused when the document becomes inactive and
restarted when it becomes active again.
- Frame timings being synchronized across consumers.
- Restarts triggered by `HTMLImageElement` applying to all consumers.
- Processing ending once a non-infinite animation plays to completion.
The tests to ensure animations are cancelled when consumers are removed
(e.g. `animated-background-image-timer-stops-when-hidden.html`) have
been updated to assert the inverse since animation state is now per
resource not per consumer.
In a future commit, ownership of animation will be transferred from
these clients to `AnimatedDecodedImageData` and we will need a way to
invalidate them for new frames.
This also revealed some `ImageProvider`s which don't yet support
animated images (e.g. `<input type="file">`, `<object>`, etc) but that
is left as a FIXME for now.
`ImageStyleValueResource` now holds a reference to a
`HTML::SharedResourceRequest` for it's entire lifetime.
We also `VERIFY` that we have created a resource (by registering a
client) before calling `ImageStyleValue::image_data` rather than
silently failing.
Previously image animations driven by `ImageStyleValueResource`
invalidated clients using `on_animate`, this was only implemented by the
`background` presentational attribute of `HTMLBodyElement`.
It now uses `notify_clients_did_update` which is implemented by all
clients.
This allows us to remove the `frame_rect` accessor.
This also fixes a bug where we computed the scaling mode based on the
clipping rect rather than the draw rect for `ImagePaintable`
WebContent no longer chooses between CPU and GPU display list players,
and the remaining callers always use Skia raster playback. Remove the
PageClient virtual and now-single-value enum, then play SVG image and
cursor display lists directly.
The <resolution> of the chosen image-set() option overrides the image's
natural resolution, so the image-set()'s natural dimensions are the
selected image's pixel dimensions divided by that resolution.
Add class-local allocation macros for operator new/delete through AK's
malloc helpers. The macros can optionally choose a HeapPartition.
Add Layout and Painting partitions, plus basic partition stats helpers.
Use the new partitions for LibWeb layout and painting object hierarchies
and layout-state side data.
Store CSS token payloads in a variant so each token only carries the
state needed by its type. Keep delimiter, number, hash, string, and
dimension data separate instead of storing every possible payload on
every token.
Use a smaller component-value token for function and block boundary
metadata. These component values only need token type, original source
text, and source positions, so avoid embedding full token payload
storage inside every Function and SimpleBlock.
Shrink CSS source positions to explicit 32-bit counters. Guard the C++
and Rust tokenizer paths against overflow. Add size assertions for the
hot Token and ComponentValue types so future growth is intentional.
Move StylePropertyMap, StylePropertyMapReadOnly, and the CSS.supports
property-name overload to Utf16FlyString. Request the UTF-16 binding
conversion path for their IDL property-name arguments.
Move PropertyNameAndID, custom property data, registered custom
properties, and Typed OM associated property names to Utf16FlyString.
This removes the FlyString storage boundary from CSS property-name
handling and lets CSSStyleProperties keep the name it receives from
CSSOM instead of converting it back to UTF-8.
Preserve unresolved values while serializing grid-row and grid-column
shorthands. The serializer can only test for the auto placement keyword
after confirming that the longhand value is a grid track placement.
Add a reduced crash test covering CSSOM serialization after assigning
var() to grid-row-end and grid-column-end.
Remove the visit_edges hook from CSS::StyleValue and stop asking CSS
properties, descriptors, computed values, and layout nodes to trace
through their style values.
Style values are refcounted data objects, so they should not be part of
the GC graph. Keeping this cleanup separate makes the later layout tree
ownership change smaller and easier to review.
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.
After `Native.css` was removed in the last commit only
`libweb-buttonfacedisabled` and `libweb-buttonfacehover` remain in use,
so the rest can be removed.
Resolving these colors was also the only use of `document` in
`ColorResolutionContex` so we can remove that too.
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.
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.
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.
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.
Add cqw/cqh/cqi/cqb/cqmin/cqmax to the unit tables and generated
helpers, then thread them through the shared length resolution path.
Length::ResolutionContext now carries the subject element and whether
its inline axis is horizontal. Container units need that extra context:
the nearest eligible query container is selected from the subject
element's flat-tree ancestors, and cqi/cqb/cqmin/cqmax map logical axes
through the subject's writing mode before resolving to a physical width
or height.
Teach Length to resolve each axis against the selected container's
content box, fall back to viewport lengths when no eligible container
exists, and mark size-container dependencies so post-layout
recomputation can happen when layout is not up to date.
Also expose the new units through Typed OM, reject them for
computationally independent `@property` initial values, and add focused
font-size coverage.
Display lists owned the accumulated visual context tree through a
ref-counted pointer. That tied visual-context state to display-list
lifetime and made compositor updates treat the two as one unit, even
though AVC trees need to become independently updateable compositor
state.
Make accumulated visual context trees plain versioned values, have each
display list store the compatible tree version, and pass the matching
tree alongside display-list updates and replay calls. Replay verifies
that the provided tree matches the display list before executing it.
This prepares the compositor for receiving AVC tree updates separately
from display-list updates: it now accepts the tree as a separate update
parameter, stores it next to the display list, and uses that stored tree
for replay and async-scroll hit testing. Nested display-list resources
carry their own tree snapshots for the same version check.
DisplayListPlayer::execute() used to flush the active painting surface
as part of replay. That made replay and submission inseparable, so
callers could not add extra painting after replay without either
accepting a stale submission boundary or flushing again.
Expose flush(PaintingSurface&) on the player and make execute() only
replay commands. Existing callers now issue an explicit flush at the
same point where the implicit flush used to happen, keeping behavior
unchanged while making the submission boundary visible to compositor
code.
Use StyleValue's computational-independence predicate when deciding
which specified values to retain for inherited-style recomputation.
Compound values such as shadows, filters, lists, and calc trees now
reuse their existing dependency tracking instead of the old bare-length
check.
Treat missing tuple entries and keyword-only edge offsets as
computationally independent. These nullable slots are part of the
parsed value representation, and the inherited dependency tracking now
uses the shared computational-independence query for specified values.
Add viewport resize coverage for media query changes that update root
font metrics while a descendant uses font-relative lengths inside
box-shadow and filter values.
Parse subgrid track listings for grid-template rows and columns,
including fixed and auto-fill name-repeat line-name lists. Preserve
the subgrid keyword through computed values and shorthand serialization,
and make interpolation discrete instead of routing subgrid lists through
the explicit track interpolation path.
Import WPT coverage for subgrid grid-template parsing and computed
values, and add text coverage for discrete subgrid track-list animation.
Record when computed properties depend on viewport metrics while
resolving lengths. Carry that information through font metrics so
font-relative lengths can be associated with viewport-sized fonts.
This keeps the dependency tracking local to style computation and gives
later viewport resize invalidation a way to find affected elements.
ImageStyleValue stored GC-managed request, stylesheet, and animation
timer references as strong GC::Ptr fields even though image style values
are refcounted objects. When such a style value outlives the GC object
that normally visits it, those fields can keep stale pointers after GC
collects the referents. On Steam this allowed a stale image resource
request to be read as unrelated image data, making carousel SVG arrows
render at the wrong size.
Store these back references as GC::Weak instead. Reachable style values
still use live requests, stylesheets, and timers normally, but detached
values observe null after the GC collects the referent and can reload or
skip the now-dead association instead of dereferencing reused GC memory.
Keep a local timer handle while installing the timeout callback so setup
does not rely on the weak member.
With the image style values no longer hiding strong GC edges, remove the
obsolete IGNORE_GC annotation from CSSStyleSheet's pending image list.
Represent WebIDL C++ types with a single CppType model that tracks
nullability, optional presence, and contained storage.
GC-like values now use GC::Ref/GC::Ptr directly, while containers choose
"plain", "Root", or "Conservative" container types depending on what
they contain. For example, sequence<Element> becomes a RootVector of
GC::Ref values, while sequence<SomeDictionary> becomes a
ConservativeVector only when the dictionary contains GC-like values.
This moves the generated bindings away from wrapping GC values in
GC::Root by default.
This has broad fallout as the types passed to interfaces for GC
objects changes almost fully across the board.
Keep animated ImageStyleValue frame advancement owned by the
style value. The current frame and loop state live there, so a
separate document scheduler would duplicate ownership of that state.
Start the ImageStyleValue timer only while it has layout clients.
Stop it when the last client unregisters, or when a finite animation
completes. Expose a document-scoped active timer count through
internals for focused regression tests.
Clear image observers when layout nodes detach. Use current-node
cleanup for per-DOM-node clearing, and explicit subtree cleanup for
tree replacement, full tree teardown, and synthetic pseudo-elements.
This keeps large document clearing linear.
Unregister generated-content image providers during layout detach
instead of waiting for GC to finalize the provider.
Cover hidden animated background images, generated content images,
layout node replacement, full layout tree teardown, and document
scoping for the internals counter.
Parameter values are absolutized at style computation time (or are
confirmed to be resolvable in the case of reification or DOMMatrix) so
there is no reason this function should fail.
All relative lengths will have been absolutized at style computation
time (or disallowed at parse time in the case of DOMMatrix) so we don't
need to resolve them again here.
LibWeb still exposed the concrete CompositorThread to Page,
Navigable, and EventHandler, so compositor IPC would have leaked the
thread implementation into callers. The old thread APIs also bundled
page presentation callbacks and main-thread wakeups into the same
object, which made it awkward for WebContent to put an actor boundary
in between.
Introduce CompositorHost and context handles as the caller-facing API,
and move shared compositor protocol values out of CompositorThread. Add
WebContentCompositor IPC endpoints and route PageHost through a paired
in-process transport. The actor owns CompositorThread with explicit
main-thread and UI presentation clients, while screenshot completion is
serialized on the WebContent event loop using request IDs.
The intention for introducing IPC here is to prepare for moving the
compositor thread into a separate process.
Similar to GC::Root<T>, make GC::RootVector<T> constructible without
explicitly passing a Heap.
This is implemented by having RootVectorBase use GC::Heap::the() for
heap-free construction.
The resolution is always absolutized at style computation time so we can
just use `Resolution::from_style_value` and select the image once in
`load_any_resources` since the layout node won't change the result.