Properly handle fallback aspect ratio for videos (#34082)

A `<video>` element with no source won't have a natural aspect ratio,
but `aspect-ratio: auto` should still fall back to a ratio of 300/150.

`used_size_as_if_inline_element_from_content_box_sizes()` was already
handling this, but other consumers of `preferred_aspect_ratio()` were
wrong. In particular, this resulted in a 0px wide inline-block:

```html
<div style="display: inline-block; border: solid">
  <video style="height: 100px; background: cyan"></video>
</div>
```

So this patch moves the fallback into `preferred_aspect_ratio()`.

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Oriol Brufau 2024-10-31 15:45:03 +01:00 committed by GitHub
parent 31566aef02
commit 851b125d4b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 70 additions and 15 deletions

View file

@ -415,11 +415,20 @@ impl ReplacedContent {
containing_block: &IndefiniteContainingBlock,
style: &ComputedValues,
) -> Option<AspectRatio> {
style.preferred_aspect_ratio(
self.inline_size_over_block_size_intrinsic_ratio(style),
containing_block.try_into().ok().as_ref(),
containing_block.style.writing_mode,
)
style
.preferred_aspect_ratio(
self.inline_size_over_block_size_intrinsic_ratio(style),
containing_block.try_into().ok().as_ref(),
containing_block.style.writing_mode,
)
.or_else(|| {
matches!(self.kind, ReplacedContentKind::Video(_)).then(|| {
let size = Self::default_object_size();
AspectRatio::from_content_ratio(
size.width.to_f32_px() / size.height.to_f32_px(),
)
})
})
}
/// <https://drafts.csswg.org/css2/visudet.html#inline-replaced-width>
@ -475,16 +484,7 @@ impl ReplacedContent {
) -> LogicalVec2<Au> {
let mode = style.writing_mode;
let intrinsic_size = self.flow_relative_intrinsic_size(style);
let intrinsic_ratio = self
.preferred_aspect_ratio(&containing_block.into(), style)
.or_else(|| {
matches!(self.kind, ReplacedContentKind::Video(_)).then(|| {
let size = Self::default_object_size();
AspectRatio::from_content_ratio(
size.width.to_f32_px() / size.height.to_f32_px(),
)
})
});
let intrinsic_ratio = self.preferred_aspect_ratio(&containing_block.into(), style);
let default_object_size =
|| LogicalVec2::from_physical_size(&Self::default_object_size(), mode);

View file

@ -570555,6 +570555,13 @@
{}
]
],
"intrinsic-size-fallback-video.html": [
"c9f2a0539147524c7e4945c6ea2ef0f05b07323f",
[
null,
{}
]
],
"keyword-sizes-for-intrinsic-contributions.tentative.html": [
"5f135d8181b023134eb24e5ec34957e3a25e6765",
[

View file

@ -0,0 +1,9 @@
[intrinsic-size-fallback-video.html]
[.wrapper 1]
expected: FAIL
[.wrapper 3]
expected: FAIL
[.wrapper 4]
expected: FAIL

View file

@ -0,0 +1,39 @@
<!DOCTYPE html>
<title>CSS Sizing Test: intrinsic contribution of videos with fallback size</title>
<link rel="author" title="Oriol Brufau" href="obrufau@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#intrinsic-sizes">
<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#intrinsic-contribution">
<meta name="assert" content="
These <video>s have no natural size nor natural aspect ratio,
but fall back to default size of 300x150 and ratio of 300/150.
Their intrinsic contributions should take these fallbacks into account.">
<style>
.wrapper {
float: left;
clear: both;
border: solid;
}
video {
background: cyan;
}
</style>
<div id="log"></div>
<div class="wrapper" data-expected-client-width="300">
<video></video>
</div>
<div class="wrapper" data-expected-client-width="200">
<video style="height: 100px"></video>
</div>
<div class="wrapper" data-expected-client-width="100">
<video style="max-height: 50px"></video>
</div>
<div class="wrapper" data-expected-client-width="400">
<video style="min-height: 200px"></video>
</div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<script>
checkLayout(".wrapper");
</script>