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.
The color stop members were RefPtr which compares by pointer identity.
This caused false positives in style invalidation when the same gradient
color values were recomputed as different objects.
The x and y members were RefPtr which compares by pointer identity.
This caused false positives in style invalidation when the same values
were recomputed as different objects.
The member type was NonnullRefPtr which compares by pointer identity.
This caused false positives in style invalidation when the same values
were recomputed as different objects.
The member types were NonnullRefPtr which compares by pointer identity.
This caused false positives in style invalidation when the same color
values were recomputed as different objects.
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.
`EdgeStyleValues` which consist of an offset of a `calc()`s which
resolves to 50% should be considered "centered" for
`SerializationMode::ResolvedValue` for the purpose of omitting the
position value from gradient serialization.
As well as being required to implement absolutization this also means we
now bypass a limitation with `LengthPercentage` where we would always
use `SerializationMode::Normal` for the constituent lengths which gains
us some WPT passes
Before this change, we'd stop collecting must-be-present identifiers
from the selector once we crossed a combinator that wasn't ' ' or '>'.
However, we can simply skip over sibling combinators and continue
collecting ancestor identifiers on the "other side" of them, since
siblings always have a shared parent.
This allows us to use the ancestor filter to quickly reject more
selectors. It also fixes a harmless bug where we believed the ancestor
filter to be useful while there were 0 ancestor hashes in the selector.
The Transformation class wasn't really accomplishing anything. It still
had to store StyleValues, so it was basically the same as
TransformationStyleValue, with extra steps to convert from one to the
other. So... let's just use TransformationStyleValue instead!
Apart from moving code around, the behavior has changed a bit. We now
actually acknowledge unresolvable parameters and return an error when
we try to produce a matrix from them. Previously we just skipped over
them, which was pretty wrong. This gets us an extra pass in the
typed-om test.
We also get some slightly different results with our transform
serialization, because we're not converting to CSSPixels and back.
Some transform-functions are not reifiable as a CSSTransformComponent,
for example a matrix() with sibling-index() in it. In that case, rather
than crashing, fall back to the basic CSSStyleValue reification.
The crash doesn't happen yet, but would with the following commit's
changes. Currently, Transformation::to_matrix() completely ignores
unsupported argument types, but in the next commit that's replaced with
TransformationStyleValue::to_matrix(), which attempts to handle them
properly.