mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Implement shrink-to-fit for abspos
This commit is contained in:
parent
efa1885e1b
commit
46f0f7d7e2
5 changed files with 48 additions and 15 deletions
|
@ -7,6 +7,7 @@ use crate::dom_traversal::{Contents, NodeExt};
|
||||||
use crate::formatting_contexts::IndependentFormattingContext;
|
use crate::formatting_contexts::IndependentFormattingContext;
|
||||||
use crate::fragments::{AnonymousFragment, BoxFragment, CollapsedBlockMargins, Fragment};
|
use crate::fragments::{AnonymousFragment, BoxFragment, CollapsedBlockMargins, Fragment};
|
||||||
use crate::geom::flow_relative::{Rect, Sides, Vec2};
|
use crate::geom::flow_relative::{Rect, Sides, Vec2};
|
||||||
|
use crate::sizing::shrink_to_fit;
|
||||||
use crate::style_ext::{ComputedValuesExt, Direction, DisplayInside, WritingMode};
|
use crate::style_ext::{ComputedValuesExt, Direction, DisplayInside, WritingMode};
|
||||||
use crate::{ContainingBlock, DefiniteContainingBlock};
|
use crate::{ContainingBlock, DefiniteContainingBlock};
|
||||||
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
||||||
|
@ -51,8 +52,15 @@ impl AbsolutelyPositionedBox {
|
||||||
display_inside: DisplayInside,
|
display_inside: DisplayInside,
|
||||||
contents: Contents<impl NodeExt<'dom>>,
|
contents: Contents<impl NodeExt<'dom>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let request_content_sizes =
|
// "Shrink-to-fit" in https://drafts.csswg.org/css2/visudet.html#abs-non-replaced-width
|
||||||
style.inline_size_is_auto() && !style.inline_box_offsets_are_both_auto();
|
let request_content_sizes = {
|
||||||
|
// If inline-size is non-auto, that value is used without shrink-to-fit
|
||||||
|
style.inline_size_is_auto() &&
|
||||||
|
// If it is, then the only case where shrink-to-fit is *not* used is
|
||||||
|
// if both offsets are non-auto, leaving inline-size as the only variable
|
||||||
|
// in the constraint equation.
|
||||||
|
!style.inline_box_offsets_are_both_non_auto()
|
||||||
|
};
|
||||||
Self {
|
Self {
|
||||||
contents: IndependentFormattingContext::construct(
|
contents: IndependentFormattingContext::construct(
|
||||||
context,
|
context,
|
||||||
|
@ -278,8 +286,20 @@ impl<'a> AbsolutelyPositionedFragment<'a> {
|
||||||
Anchor::End(end) => cbis - end - pb.inline_sum() - margin.inline_sum(),
|
Anchor::End(end) => cbis - end - pb.inline_sum() - margin.inline_sum(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME(nox): shrink-to-fit.
|
if self
|
||||||
available_size
|
.absolutely_positioned_box
|
||||||
|
.contents
|
||||||
|
.as_replaced()
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
// FIXME: implement https://drafts.csswg.org/css2/visudet.html#abs-replaced-width
|
||||||
|
available_size
|
||||||
|
} else {
|
||||||
|
shrink_to_fit(
|
||||||
|
&self.absolutely_positioned_box.contents.inline_content_sizes,
|
||||||
|
available_size,
|
||||||
|
)
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let containing_block_for_children = ContainingBlock {
|
let containing_block_for_children = ContainingBlock {
|
||||||
|
|
|
@ -65,10 +65,7 @@ pub(crate) fn outer_inline_content_sizes_and_percentages(
|
||||||
let specified = specified.map(|lp| lp.as_length());
|
let specified = specified.map(|lp| lp.as_length());
|
||||||
// The (inner) min/max-content are only used for 'auto'
|
// The (inner) min/max-content are only used for 'auto'
|
||||||
let mut outer = match specified.non_auto().flatten() {
|
let mut outer = match specified.non_auto().flatten() {
|
||||||
None => inner_content_sizes
|
None => expect(inner_content_sizes).clone(),
|
||||||
.as_ref()
|
|
||||||
.expect("Accessing content size that was not requested")
|
|
||||||
.clone(),
|
|
||||||
Some(length) => ContentSizes {
|
Some(length) => ContentSizes {
|
||||||
min_content: length,
|
min_content: length,
|
||||||
max_content: length,
|
max_content: length,
|
||||||
|
@ -96,3 +93,20 @@ pub(crate) fn outer_inline_content_sizes_and_percentages(
|
||||||
|
|
||||||
(outer, pbm_percentages)
|
(outer, pbm_percentages)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// https://drafts.csswg.org/css2/visudet.html#shrink-to-fit-float
|
||||||
|
pub(crate) fn shrink_to_fit(
|
||||||
|
content_sizes: &Option<ContentSizes>,
|
||||||
|
available_size: Length,
|
||||||
|
) -> Length {
|
||||||
|
let content_sizes = expect(content_sizes);
|
||||||
|
available_size
|
||||||
|
.max(content_sizes.min_content)
|
||||||
|
.min(content_sizes.max_content)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expect(content_sizes: &Option<ContentSizes>) -> &ContentSizes {
|
||||||
|
content_sizes
|
||||||
|
.as_ref()
|
||||||
|
.expect("Accessing content size that was not requested")
|
||||||
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ pub(crate) trait ComputedValuesExt {
|
||||||
fn writing_mode(&self) -> (WritingMode, Direction);
|
fn writing_mode(&self) -> (WritingMode, Direction);
|
||||||
fn writing_mode_is_horizontal(&self) -> bool;
|
fn writing_mode_is_horizontal(&self) -> bool;
|
||||||
fn inline_size_is_auto(&self) -> bool;
|
fn inline_size_is_auto(&self) -> bool;
|
||||||
fn inline_box_offsets_are_both_auto(&self) -> bool;
|
fn inline_box_offsets_are_both_non_auto(&self) -> bool;
|
||||||
fn box_offsets(&self) -> flow_relative::Sides<LengthPercentageOrAuto>;
|
fn box_offsets(&self) -> flow_relative::Sides<LengthPercentageOrAuto>;
|
||||||
fn box_size(&self) -> flow_relative::Vec2<LengthPercentageOrAuto>;
|
fn box_size(&self) -> flow_relative::Vec2<LengthPercentageOrAuto>;
|
||||||
fn padding(&self) -> flow_relative::Sides<LengthPercentage>;
|
fn padding(&self) -> flow_relative::Sides<LengthPercentage>;
|
||||||
|
@ -78,7 +78,7 @@ impl ComputedValuesExt for ComputedValues {
|
||||||
matches!(size, Size::Auto)
|
matches!(size, Size::Auto)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inline_box_offsets_are_both_auto(&self) -> bool {
|
fn inline_box_offsets_are_both_non_auto(&self) -> bool {
|
||||||
let position = self.get_position();
|
let position = self.get_position();
|
||||||
let offsets = if self.writing_mode_is_horizontal() {
|
let offsets = if self.writing_mode_is_horizontal() {
|
||||||
(position.left, position.right)
|
(position.left, position.right)
|
||||||
|
@ -87,7 +87,10 @@ impl ComputedValuesExt for ComputedValues {
|
||||||
};
|
};
|
||||||
matches!(
|
matches!(
|
||||||
offsets,
|
offsets,
|
||||||
(LengthPercentageOrAuto::Auto, LengthPercentageOrAuto::Auto)
|
(
|
||||||
|
LengthPercentageOrAuto::LengthPercentage(_),
|
||||||
|
LengthPercentageOrAuto::LengthPercentage(_),
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[containing-block-008.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[containing-block-010.xht]
|
|
||||||
expected: FAIL
|
|
Loading…
Add table
Add a link
Reference in a new issue