Preserve fractional pinch focal points when updating the
main-thread visual viewport. Only coalesce queued pinch events
that share the same focal point and modifiers so WebContent sees
a transform equivalent to the event sequence seen by the
compositor.
Also clear a speculative async visual viewport transform once
async wheel or pinch admission becomes blocked. At that point the
compositor can no longer advance that transform to match
WebContent. Use a looser translation tolerance when comparing
visual viewport transforms to account for subpixel differences in
the compositor and main-thread math.
Keep the cached equality precheck, but compute the set hash with
order-independent aggregate values instead of materializing and sorting
the per-property hashes.
This avoids allocation and sorting in a hot equality path while leaving
correctness to the existing full property comparison after hash matches.
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.
Separate MediaQueryList change reporting from stylesheet media rule
invalidation. Creating matchMedia() objects evaluates their own baseline
state, but should not make the next style update walk all active
stylesheets when the media environment has not changed.
This avoids continuous stylesheet media query reevaluation during
YouTube video playback, where repeated matchMedia() creation can make
style flushes do unnecessary work.
Keep the non-subject :has() affected bit across element style
recomputation. This bit can be discovered while matching descendant
selectors, and recomputing the anchor itself may not revisit those
selectors before a later mutation needs the dependency for targeted
:has() invalidation.
This avoids stale descendant style after targeted :has() invalidation
when a previous recompute cleared the anchor-side dependency metadata.
Repeated style invalidation tests cover the previously flaky case.
Property invalidation inside :nth-child(... of ...) used to become a
whole-subtree invalidation plan. That is broader than needed for
property changes that only affect the filtered sibling list, such as
:has() becoming true or false for one sibling.
Add an invalidation plan bit that marks the element and structurally
affected siblings instead. Keep whole-subtree invalidation when a
stronger plan already requires it, and cover both :nth-child and
:nth-last-child filters with :has() regression tests.
Use structural-position pseudo-classes as subject match filters while
building style invalidation plans. Selectors such as `.menu:has(> .flag)
> :first-child` can then carry a concrete right-hand match set instead
of widening the `:has()` invalidation plan to the whole subtree.
Keep these pseudo-classes out of trigger-property sets since structural
topology mutations are handled separately. This avoids adding unrelated
cold topology recomputes while still letting the affected boundary
children be invalidated directly.
Add a regression test that mutates the child class used by `:has()` and
asserts that the old whole-subtree path does not produce excessive no-op
style recomputations.
Feature-filter :not() arguments in :has() when the same compound also
has a concrete tag, id, class, or attribute selector. Bare negations
still stay conservative, but anchored negations no longer make unrelated
subtree mutations walk every :has() candidate.
Also avoid installing the whole-subtree :has() fallback for rightmost
complex :is()/:where() arguments that only use descendant or child
combinators. Keep the fallback for non-rightmost and sibling-combinator
cases where the existing plan cannot represent the nested selector
context.
Add counter-based style invalidation coverage for both cases.
Record hover, focus, focus-visible, focus-within, and target pseudo
classes in :has() invalidation metadata. This lets the existing
property invalidation path schedule :has() ancestor invalidation only
for scopes whose :has() selectors mention the changed pseudo-class.
Interaction pseudo-class invalidation previously scheduled :has()
ancestor invalidation for every style scope containing any :has()
selector. That kept selectors like .wrapper:has(:focus) * correct, but
also caused unrelated hover and focus changes to fan out through broad
:has() descendant invalidation rules.
Update style invalidation coverage so unrelated hover changes avoid the
extra :has() walk, while a descendant :has(:focus) rule still restyles
its affected descendants when focus changes.
Now that Badge can have multiple types, and a Badge of a derived class
can convert into a Badge of the superclass, we can simplify a few method
signatures and overloads.
The spec doesn't say how to handle this so we just match Chrome's
behavior of throwing a `TypeError` (without clearing the existing
value).
Fixes#9969.
Fixes#9970.
Stop emitting every generated CSS property accessor as an IDL attribute.
Instead, generate a compact CSSStyleProperties initializer that installs
all property aliases from a table and dispatches through one native
function class carrying the UTF-16 property name.
This keeps the generated binding file focused on cssFloat and moves the
large property list into a simple generated table.
Remove the PropertyNameAndID::from_name overload that accepted
FlyString. Parser declarations still store their token names as
FlyString, but the conversion to UTF-16 now happens explicitly at those
boundaries.
Move DescriptorNameAndID to Utf16FlyString so CSS descriptor APIs can
keep using the CSSOM property-name string without round-tripping through
FlyString.
Keep parser declaration tokens and DevTools error payloads on their
existing FlyString types at their boundaries.
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.
Move the remaining CSSStyleDeclaration property-name APIs to
Utf16FlyString. This lets CSSOM binding and generated accessor code
pass JS property names without first constructing FlyString values.
Keep internal custom-property and descriptor storage unchanged for now.
Those remaining FlyString conversions are at storage boundaries that
will be migrated in follow-up commits.
Change get_property_value() to take a Utf16FlyString so generated CSS
property accessors can pass their JS property names through without
constructing FlyString instances first.
Keep the existing internal descriptor and custom-property storage shape
for now, and convert at those boundaries while the remaining CSS
property APIs are migrated separately.
When an element was affected by :has() in subject position,
pending :has() mutation invalidation also applied the pseudo-class
invalidation plan for that element. If the same element had ever been
observed in a non-subject :has() selector, that plan could invalidate
the element's whole descendant subtree even when the mutation could
only require the subject element itself to recompute style.
Keep subject-position :has() invalidation to the element itself, and
run the descendant fanout only for non-subject involvement after the
existing mutation feature filter says that fanout may be affected.
Track the strongest invalidation applied to each anchor, so a later
batched mutation can still upgrade earlier anchor-only work to a
descendant fanout.
Extend the filter to treat known state pseudo-classes as concrete
mutation features, so a :hover mutation does not conservatively match
unrelated selectors such as :has(dialog:modal).
Scope boundary selectors are kept conservative where needed: when an
@scope boundary contains :has(), the scope root's match can activate or
deactivate style rules for descendants, so it still records descendant
involvement.
Add coverage for unrelated hover and batched mutation cases on elements
whose ancestors have both subject and non-subject :has() involvement,
ensuring descendant no-op recomputation stays bounded without dropping
required descendant fanout.
Track last-child and backward positional selector dependencies
separately on parent nodes. A last-child or only-child selector can only
change the element at the trailing edge, so insertions and removals can
invalidate that element directly instead of walking every previous
sibling.
Keep the previous-sibling walk for selectors such as nth-last-child and
last-of-type, where every previous element's from-end position may
change.
Include tag and attribute selectors in guarded pseudo-class invalidation
plans. This keeps selectors like a:hover .target from applying work to
unrelated descendants when :hover changes on other elements.
Store both original and lowercase attribute names for invalidation keys.
HTML attribute mutations still hit lowercase selector buckets, while SVG
and MathML selectors such as [viewBox] keep their case-sensitive guards.
Use the same names for :has() metadata and mutation feature filtering so
attribute changes do not get filtered out after metadata lookup.
Match tag invalidation properties against lowercased local names, like
invalidation data and rule cache buckets do. The regression tests cover
SVG hover fanout and case-sensitive :has() attribute mutation.
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.
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.
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 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.
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.
The `font-family` descriptor may not be present, so handle that
gracefully. We already did so, but now it's an official part of the
spec.
Corresponds to:
75299e7be1cfb59f593a
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.
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.
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.