mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Simplify the computation of CAPMIN (#33577)
CAPMIN is the largest min-content contribution of the table captions. In Servo, the standard way to compute min/max-content contributions is `outer_inline_content_sizes()`, so just use that instead of reinventing the wheel. This also fixes cyclic percentages to resolve consistently with normal block boxes. Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
d110d8710a
commit
5d269a9036
4 changed files with 116 additions and 45 deletions
|
@ -201,14 +201,11 @@ impl IndependentFormattingContext {
|
||||||
auto_block_size_stretches_to_containing_block: bool,
|
auto_block_size_stretches_to_containing_block: bool,
|
||||||
) -> ContentSizes {
|
) -> ContentSizes {
|
||||||
match self {
|
match self {
|
||||||
Self::NonReplaced(non_replaced) => sizing::outer_inline(
|
Self::NonReplaced(non_replaced) => non_replaced.outer_inline_content_sizes(
|
||||||
&non_replaced.style.clone(),
|
layout_context,
|
||||||
containing_block,
|
containing_block,
|
||||||
auto_minimum,
|
auto_minimum,
|
||||||
auto_block_size_stretches_to_containing_block,
|
auto_block_size_stretches_to_containing_block,
|
||||||
|containing_block_for_children| {
|
|
||||||
non_replaced.inline_content_sizes(layout_context, containing_block_for_children)
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
Self::Replaced(replaced) => sizing::outer_inline(
|
Self::Replaced(replaced) => sizing::outer_inline(
|
||||||
&replaced.style,
|
&replaced.style,
|
||||||
|
@ -291,6 +288,24 @@ impl NonReplacedFormattingContext {
|
||||||
))
|
))
|
||||||
.1
|
.1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn outer_inline_content_sizes(
|
||||||
|
&mut self,
|
||||||
|
layout_context: &LayoutContext,
|
||||||
|
containing_block: &IndefiniteContainingBlock,
|
||||||
|
auto_minimum: &LogicalVec2<Au>,
|
||||||
|
auto_block_size_stretches_to_containing_block: bool,
|
||||||
|
) -> ContentSizes {
|
||||||
|
sizing::outer_inline(
|
||||||
|
&self.style.clone(),
|
||||||
|
containing_block,
|
||||||
|
auto_minimum,
|
||||||
|
auto_block_size_stretches_to_containing_block,
|
||||||
|
|containing_block_for_children| {
|
||||||
|
self.inline_content_sizes(layout_context, containing_block_for_children)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NonReplacedFormattingContextContents {
|
impl NonReplacedFormattingContextContents {
|
||||||
|
|
|
@ -769,49 +769,20 @@ impl<'a> TableLayout<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute CAPMIN: <https://drafts.csswg.org/css-tables/#capmin>
|
/// Compute CAPMIN: <https://drafts.csswg.org/css-tables/#capmin>
|
||||||
fn compute_caption_minimum_inline_size(
|
fn compute_caption_minimum_inline_size(&mut self, layout_context: &LayoutContext) -> Au {
|
||||||
&mut self,
|
|
||||||
layout_context: &LayoutContext,
|
|
||||||
writing_mode: WritingMode,
|
|
||||||
) -> Au {
|
|
||||||
self.table
|
self.table
|
||||||
.captions
|
.captions
|
||||||
.iter()
|
.iter()
|
||||||
.map(|caption| {
|
.map(|caption| {
|
||||||
let mut context = caption.context.borrow_mut();
|
let mut context = caption.context.borrow_mut();
|
||||||
let padding = context
|
context
|
||||||
.style
|
.outer_inline_content_sizes(
|
||||||
.padding(writing_mode)
|
|
||||||
.percentages_relative_to(Au::zero());
|
|
||||||
let border = context.style.border_width(writing_mode);
|
|
||||||
let margin = context
|
|
||||||
.style
|
|
||||||
.margin(writing_mode)
|
|
||||||
.percentages_relative_to(Au::zero())
|
|
||||||
.auto_is(Au::zero);
|
|
||||||
|
|
||||||
let padding_border_sums = LogicalVec2 {
|
|
||||||
inline: padding.inline_sum() + border.inline_sum() + margin.inline_sum(),
|
|
||||||
block: padding.block_sum() + border.block_sum() + margin.block_sum(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let (size, min_size, max_size, size_is_auto) =
|
|
||||||
get_outer_sizes_from_style(&context.style, writing_mode, &padding_border_sums);
|
|
||||||
|
|
||||||
// If an inline size is defined it should serve as the upper limit and lower limit
|
|
||||||
// of the caption inline size.
|
|
||||||
if !size_is_auto {
|
|
||||||
size.inline
|
|
||||||
} else {
|
|
||||||
let style = context.style.clone();
|
|
||||||
let inline_content_sizes = context.inline_content_sizes(
|
|
||||||
layout_context,
|
layout_context,
|
||||||
&IndefiniteContainingBlock::new_for_style(&style),
|
&IndefiniteContainingBlock::new_for_style(&self.table.style),
|
||||||
);
|
&LogicalVec2::zero(),
|
||||||
inline_content_sizes.min_content + padding_border_sums.inline
|
false, /* auto_block_size_stretches_to_containing_block */
|
||||||
}
|
)
|
||||||
.min(max_size.inline)
|
.min_content
|
||||||
.max(min_size.inline)
|
|
||||||
})
|
})
|
||||||
.max()
|
.max()
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
|
@ -1666,8 +1637,7 @@ impl<'a> TableLayout<'a> {
|
||||||
) -> IndependentLayout {
|
) -> IndependentLayout {
|
||||||
let table_writing_mode = containing_block_for_children.style.writing_mode;
|
let table_writing_mode = containing_block_for_children.style.writing_mode;
|
||||||
let grid_min_max = self.compute_grid_min_max(layout_context, table_writing_mode);
|
let grid_min_max = self.compute_grid_min_max(layout_context, table_writing_mode);
|
||||||
let caption_minimum_inline_size =
|
let caption_minimum_inline_size = self.compute_caption_minimum_inline_size(layout_context);
|
||||||
self.compute_caption_minimum_inline_size(layout_context, table_writing_mode);
|
|
||||||
self.compute_table_width(
|
self.compute_table_width(
|
||||||
containing_block_for_children,
|
containing_block_for_children,
|
||||||
containing_block_for_table,
|
containing_block_for_table,
|
||||||
|
@ -2638,7 +2608,7 @@ impl Table {
|
||||||
let mut table_content_sizes = layout.compute_grid_min_max(layout_context, writing_mode);
|
let mut table_content_sizes = layout.compute_grid_min_max(layout_context, writing_mode);
|
||||||
|
|
||||||
let mut caption_minimum_inline_size =
|
let mut caption_minimum_inline_size =
|
||||||
layout.compute_caption_minimum_inline_size(layout_context, writing_mode);
|
layout.compute_caption_minimum_inline_size(layout_context);
|
||||||
if caption_minimum_inline_size > table_content_sizes.min_content ||
|
if caption_minimum_inline_size > table_content_sizes.min_content ||
|
||||||
caption_minimum_inline_size > table_content_sizes.max_content
|
caption_minimum_inline_size > table_content_sizes.max_content
|
||||||
{
|
{
|
||||||
|
|
7
tests/wpt/meta/MANIFEST.json
vendored
7
tests/wpt/meta/MANIFEST.json
vendored
|
@ -565066,6 +565066,13 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"caption-cyclic-percentage.html": [
|
||||||
|
"3ba59491fa47496ac4f6562ad94bfde385a47e57",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"caption-side-1.html": [
|
"caption-side-1.html": [
|
||||||
"302e51ae239307a49c239bf0ad5ade17a5c9d940",
|
"302e51ae239307a49c239bf0ad5ade17a5c9d940",
|
||||||
[
|
[
|
||||||
|
|
79
tests/wpt/tests/css/css-tables/caption-cyclic-percentage.html
vendored
Normal file
79
tests/wpt/tests/css/css-tables/caption-cyclic-percentage.html
vendored
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<title>Cyclic percentage sizes on table captions</title>
|
||||||
|
<link rel="author" title="Oriol Brufau" href="obrufau@igalia.com">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-tables/#table-caption">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#cyclic-percentage-contribution">
|
||||||
|
<meta assert="
|
||||||
|
Cyclic percentages on a table caption behave like in a normal block box.
|
||||||
|
Note that browsers don't agree with the spec on the exact behavior
|
||||||
|
(https://github.com/w3c/csswg-drafts/issues/10969),
|
||||||
|
but they should still pass this test.">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.test {
|
||||||
|
display: inline-block;
|
||||||
|
border: 10px solid;
|
||||||
|
}
|
||||||
|
.min-width > .test > div {
|
||||||
|
min-width: calc(100px + 0%);
|
||||||
|
}
|
||||||
|
.width > .test > div {
|
||||||
|
width: calc(100px + 0%);
|
||||||
|
}
|
||||||
|
.max-width > .test > div {
|
||||||
|
max-width: calc(100px + 0%);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<article class="min-width">
|
||||||
|
<p>These 2 rectangles should be equally wide:</p>
|
||||||
|
<div class="test">
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="test">
|
||||||
|
<div style="display: table-caption"></div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="width">
|
||||||
|
<p>These 2 rectangles should be equally wide:</p>
|
||||||
|
<div class="test">
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="test">
|
||||||
|
<div style="display: table-caption"></div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="max-width">
|
||||||
|
<p>These 2 rectangles should be equally wide:</p>
|
||||||
|
<div class="test">
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="test">
|
||||||
|
<div style="display: table-caption"></div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script>
|
||||||
|
for (let article of document.querySelectorAll("article")) {
|
||||||
|
test(function() {
|
||||||
|
let elements = article.querySelectorAll(".test");
|
||||||
|
assert_greater_than(elements.length, 1, "Need more than 1 element to compare");
|
||||||
|
let expected = elements[0].offsetWidth;
|
||||||
|
for (let i = 1; i < elements.length; ++i) {
|
||||||
|
assert_equals(
|
||||||
|
elements[i].offsetWidth,
|
||||||
|
expected,
|
||||||
|
`Element #${i + 1} is as wide as the 1st one`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, article.className);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue