layout: Never stretch indefinite intrinsic keywords other than auto (#34672)

Consider:
```html
<div style="position: relative; width: 50px; height: 50px; border: solid; margin: 5px">
  <div style="position: absolute; top: 0; bottom: 0; height: max-content">
    <canvas width="25" height="25" style="background: cyan; height: 100%"></canvas>
  </div>
</div>
```

In order to determine the inline min/max-content sizes, we need a
tentative block size as the input, which only takes extrinsic values
into account.

In this case `height: max-content` is intrinsic, so we were treating it
as `height: initial`, which would behave as a definite `height: stretch`.
Therefore, the canvas was able to resolve its percentage.

However, it seems weird to treat an explicitly intrinsic keyword in an
extrinsic way, and Blink doesn't do it. So now we treat the tentative
block size as indefinite, therefore the percentage behaves as auto.

This adds a new test, we were previously failing 6 subtests, now only 3.

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Oriol Brufau 2024-12-18 23:21:47 +01:00 committed by GitHub
parent 017b12a627
commit ab270f3d52
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 329 additions and 6 deletions

View file

@ -799,7 +799,6 @@ impl<'a> AbsoluteAxisSolver<'a> {
// A LazyCell will only invoke it once if needed, and then reuse the result.
let content_size = get_content_size.map(LazyCell::new);
let solve_size = |initial_behavior, stretch_size: Au| -> SizeConstraint {
let initial_is_stretch = initial_behavior == Size::Stretch;
let stretch_size = stretch_size.max(Au::zero());
if let Some(ref content_size) = content_size {
let preferred_size = Some(self.computed_size.resolve(
@ -816,10 +815,12 @@ impl<'a> AbsoluteAxisSolver<'a> {
.resolve_non_initial(stretch_size, content_size);
SizeConstraint::new(preferred_size, min_size, max_size)
} else {
let preferred_size = self
.computed_size
.maybe_resolve_extrinsic(Some(stretch_size))
.or(initial_is_stretch.then_some(stretch_size));
let preferred_size = if self.computed_size.is_initial() {
initial_behavior
} else {
self.computed_size
}
.maybe_resolve_extrinsic(Some(stretch_size));
let min_size = self
.computed_min_size
.maybe_resolve_extrinsic(Some(stretch_size))