When an image has no intrinsic dimensions but has an intrinsic aspect
ratio, the CSS default sizing algorithm should resolve its size as a
contain constraint against the default object size. Previously, we
returned the default size directly, which caused such images to stretch
to fill the entire background positioning area. The SVG's default
`preserveAspectRatio` would then center the content within that
oversized viewport, making the image appear horizontally mispositioned.
The selector matching code bypassed the pseudo-element type check for
`::part()` selectors to support compound selectors like
`::part(foo)::before`. This caused bare ::part() declarations to leak
into unrelated pseudo-elements like ::selection.
Fix this by finding any additional pseudo-element beyond ::part() in the
selector and verifying it matches the target.
The spec says that the `system` descriptor defaults to `symbolic` but
previously we just ignored any `@counter-style` rules without a `system`
descriptor
Previously we just passed around a reference to the `CounterStyle`
stored on `Document::registered_counter_styles` but this won't be
possible for anonymous counter styles (i.e. those created by the
`<symbols()>` function)
Add unsafe_layout_node(), unsafe_paintable(), and unsafe_paintable_box()
accessors that skip layout-staleness verification. These are for use in
contexts where accessing layout/paintable data is legitimate despite
layout not being up to date: tree construction, style recalculation,
painting, animation interpolation, DOM mutation, and invalidation
propagation.
Also add wrapper APIs on Node to centralize common patterns:
- set_needs_display() wraps if (unsafe_paintable()) ...set_needs_display
- set_needs_paint_only_properties_update() wraps similar
- set_needs_layout_update() wraps if (unsafe_layout_node()) ...
And add Document::layout_is_up_to_date() which checks whether layout
tree update flags are all clear.
We have a common pattern of creating a `WeakPtr<T>` from a reference and
passing that into a lambda, to then take the strong ref when the lambda
is executed. Add `weak_callback(Weakable, lambda)` that returns a lambda
that only invokes the callback if a strong ref exists, and passes it as
the first argument.
Stop converting between CSS and device pixels as part of rendering - the
display list should be as simple as possible, so convert to DevicePixels
once when constructing the display list.
Replace the unsafe HashTable<GC::Weak<DOM::Node>> with
GC::WeakHashSet<DOM::Node>. The null check in the iteration loop is
no longer needed since WeakHashSet's iterator skips dead entries.
As FontFaces are added or removed from a FontFaceSet, and as they load
or fail, the FontFaceSet moves them between a few different lists, and
updates its loading/loaded status. In the spec, this is how the
FontFaceSet.[[ReadyPromise]] gets fulfilled: When the document has
finished loading and FontFaceSet.[[LoadingFonts]] is empty, it resolves
the promise.
To support this, FontFace now keeps a set of FontFaceSets that it is
contained in.
This lets us remove the non-spec resolve_ready_promise() call in
EventLoop which was sometimes triggering before any fonts had attempted
to load.
As noted, there's a spec issue with the ready promise: If nothing
modifies the document's fonts, then it would never resolve. My ad-hoc
fix is to also switch the FontFaceSet to the loaded state if it is
empty, which appears to solve the issues but is not ideal.
The current css-font-loading spec doesn't define a constructor for this,
and from our own code we can rely on initializing things in the C++
constructor.
The spec requires us to follow the steps in FontFace::load() whenever a
font is loaded. The simplest way to do so, is to make that the only way
we load fonts. :^)
To support this, FontFace::load() uses its connected CSSFontFaceRule's
ParsedFontFace if it's available.
The 1 regression in generic-family-keywords-003.html seems to be a false
positive: we don't support the system-ui font keyword.
Corresponds to:
f0635e6e10
Assigning null to a non-nullable DOMString didn't make sense.
Apparently our bindings generator didn't care though. It's already
nullable on the C++ side by being an Optional<String>.
We now only allocate a StyleValueVector if we know absolutization has
caused a value to change.
This change also avoids a double StyleValue::absolutized() computation.
Previously we only supported a subset of the predefined counter styles,
we now respect counter styles defined by `@counter-style` rules when
resolving the value of `counter()` and `counters()` functions
There are some predefined counter styles (such as the longhand east
asian ones) which are too complex to be defined here and will need to be
implemented ad-hoc, this remains as a FIXME for now.
The tricky bit of this is resolving cycles in extending rules and
ensuring that counter styles are registered in the required order for
extension (i.e. for any pair of extended/extending rules the extended
one should be registered first).