Previously we computed font properties separately from other properties
for two reasons:
1) These font properties were computed using a different length
resolution context than the rest of the properties.
2) These properties were required to be computed before creating the
length resolution context for the rest of the properties.
The first issue was solved in the previous commit by introducing a
generic method to get the computation context for a property, and
the second is solved in this commit by computing properties in the
required order.
This simplifies the code a bit and opens up some opportunities for
optimization.
The computation context used is the main thing distinguishing the
computation of font/non-font properties so having a generic method to
handle this will allow us to consolidate logic between the two.
Replace per-element OrderedHashMap storage for custom properties with
a RefCounted chain (CustomPropertyData) that enables structural
sharing. Each chain node stores only the properties declared directly
on its element, with a parent pointer to the inherited chain.
Elements that don't override any custom properties share the parent's
data directly (just a RefPtr copy). During cascade, only entries that
actually differ from the parent are stored in own_values - the rest
are inherited through the chain. During var() resolution, resolved
values are compared against the parent's and matching entries are
dropped, enabling further sharing.
The chain uses a depth limit (max 32) with flattening, plus
absorption of small parent nodes (threshold 8) to keep lookups fast.
This reduces custom property memory from ~79 MB to ~5.7 MB on
cloudflare.com.
The author_rules vector always contains at least one layer (the
unlayered entry), so checking is_empty() was always false. Instead,
check whether any layer actually contains rules.
These get computed to an equivalent RGBColorStyleValue.
To support this, we now store the computed color-scheme on the
ComputationContext when computing properties that might contain a color.
This has a nice bonus of correcting the css-accent-color test's result.
Every user of this actually wants an ancestor in the flat tree - taking
things like `<slot>` into account. So rename it and adjust its behavior
to use that.
In a future commit we will require this to be in it's computed form
before calling `ComputedProperties::computed_font_list()`.
We will also depend on other properties (e.g. `font-kerning`,
`font-variant-*`) but these are unaffected by computation.
The main change here is that we now properly absolutize values which
means we now support `random()` and `sibling-{count,index}()`
We are also more consistent with how we handle computation for the other
font properties
Previously we implemented an all encompassing `MathDepthStyleValue`
specifically for the `math-depth` property, this was unnecessary since
we can represent `auto-add` and `<integer>` using existing `StyleValue`
classes.
This brings the values created from parsing in line with those set via
`StylePropertyMap` which allows us to simplify computation
Replace two uses of heap-allocated Bitmap with stack-allocated
FixedBitmap. The sizes are known at compile time, so there's no need
to hit malloc for these.
This means we now allow oblique angles when parsing the `font`
shorthand.
This also required us to rename the existing `FontStyle` enum to
`FontStyleKeyword`
Previously we would do two cascaded property lookups per property during
style computation - the first to get the value of the property and the
second to check whether it was marked as important. We now do this as a
single lookup to save some unnecessary work.
This adds visit_edges(Cell::Visitor&) methods to various helper structs
that contain GC pointers, and makes sure they are called from owning
GC-heap-allocated objects as needed.
These were found by our Clang plugin after expanding its capabilities.
The added rules will be enforced by CI going forward.
Previously the logic to compute transitions was split across
`ComputedProperties`, `StyleComputer`, and `Animatable` - this commit
consolidates it all in `ComputedProperties`
The `:has()` pseudo-class requires traversing descendants (or siblings)
to find matches.
With this change we cache results keyed by `(Selector*, Element*)`
pairs. The cache is stored in `StyleComputer` and cleared at the start
of each style computation pass in `Document::update_style()`.
When `:has()` uses a descendant combinator and we find a match, we also
cache that all ancestors between the matching descendant and the
anchor match. For example with `div:has(.target)`:
```html
<div id="A"> <!-- checking :has(.target) here -->
<div id="B">
<div id="C">
<span class="target"/>
</div>
</div>
</div>
```
When we find `.target` while checking `div#A`, we also cache that
`div#B` and `div#C` match `:has(.target)` since they also contain
`.target`. Later when styling these elements, we get cache hits and skip
traversal.
...when the style is `none` or `hidden`. `outline-width` is not affected
by `outline-style: none` at all.
In our codebase, that means doing the border-width conversion when
assigning to ComputedValues.
Corresponds to:
2a3d1e4d1009f11f2ef9
In level 2 of the web animations spec, times are no longer always
measures in milliseconds, they can also be percents when dealing with
progress-based (i.e. scroll-based) timelines.
We don't actually support percent times yet but this change will make it
easier to implement when we do.
Web Animations Level 2 disallows setting some `AnimationEffect` timing
values (start delay, end delay, iteration duration) directly and instead
allows authors to set the specified values which are then normalized
into the actual used values taking into account the type of the
associated timeline (i.e. progress- vs time-based)
This makes us consistent with how we handle this value within the
`background` shorthand and allows us to remove the special handling in
`StyleComputer::for_each_property_expanding_shorthands`
Computing the font for an element in `compute_font` is premature since
we are yet to apply animated properties - instead we should compute the
value on the fly (with a cache to avoid unnecessary work) to ensure we
are respecting the latest values
Font computation and loading is distinct enough from style computation
that it makes more sense to have this in it's own class.
This will be useful later when we move the font loading process to
`ComputedProperties` in order to respect animated values.
Since we resolve any relative lengths at compute time there's no need
for the value to be passed around as a `NumberOrCalculated` and we can
just resolve it within `ComputedProperties::font_variation_settings`.
The only place this is used it is used with value_or so there's no need
to return it is an `Optional`.
This is only used for loading fonts (which occurs during style
computation) so there's no need to store it in `ComputedValues`
From the spec:
> The owning element of a transition refers to the element or
pseudo-element to which the transition-property property was applied
that generated the animation.
https://drafts.csswg.org/css-transitions-2/#owning-element
Previously we only stored the element.
An upcoming commit will migrate the contents of Headers.h/cpp to LibHTTP
for use outside of LibWeb. These CORS and MIME helpers depend on other
LibWeb facilities, however, so they cannot be moved.
Previously we would only update these if:
a) We had a cascaded value for `transition-property`
b) The source of that cascaded value had changed since we last
registered transitions
This meant that there were a lot of changes we didn't apply:
- Changes exclusively to properties other than `transition-property`
(e.g. `transition-duration`, `transition-behavior`, etc)
- Removing the `transition-property` property
- Updating the `transition-property` property in a way that didn't
change it's source (e.g. setting it within inline-style)
Unfortunately this does mean that we now register transitions for all
properties on most elements since "all" is the initial value for
"transition-property" which isn't great for performance, but that can be
looked at in later commits.
Also renames the `clear_transitions` function to clarify this doesn't
affect the associated transition animations.
This fixes an issue where transitions weren't being cancelled when the
relevant transition-property entry was no longer present