aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout
diff options
context:
space:
mode:
authorOriol Brufau <obrufau@igalia.com>2024-09-20 16:48:27 +0200
committerGitHub <noreply@github.com>2024-09-20 14:48:27 +0000
commit9597390d2bc6f68492cc9fae6287d0a456cdb3c1 (patch)
tree470d803926620b39f272c38eb455ec4093eec48e /components/layout
parent4bde9af5159b18eba1b65256de0d2dda328a1eb2 (diff)
downloadservo-9597390d2bc6f68492cc9fae6287d0a456cdb3c1.tar.gz
servo-9597390d2bc6f68492cc9fae6287d0a456cdb3c1.zip
Enable min-content, max-content, fit-content and stretch (#33492)
For the sizing properties. We don't actually support them yet, just treating them as the initial value. Signed-off-by: Oriol Brufau <obrufau@igalia.com> Co-authored-by: Martin Robinson <mrobinson@igalia.com>
Diffstat (limited to 'components/layout')
-rw-r--r--components/layout/block.rs49
-rw-r--r--components/layout/flex.rs7
-rw-r--r--components/layout/floats.rs9
-rw-r--r--components/layout/fragment.rs8
-rw-r--r--components/layout/model.rs34
-rw-r--r--components/layout/multicol.rs14
-rw-r--r--components/layout/table.rs11
-rw-r--r--components/layout/table_cell.rs12
-rw-r--r--components/layout/table_row.rs16
-rw-r--r--components/layout/table_wrapper.rs43
10 files changed, 88 insertions, 115 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs
index cbfa80798e0..bceb82b572d 100644
--- a/components/layout/block.rs
+++ b/components/layout/block.rs
@@ -419,24 +419,24 @@ impl CandidateBSizeIterator {
// If that is not determined yet by the time we need to resolve
// `min-height` and `max-height`, percentage values are ignored.
- let block_size = match fragment.style.content_block_size() {
- Size::Auto => MaybeAuto::Auto,
- Size::LengthPercentage(ref lp) => {
- MaybeAuto::from_option(lp.maybe_to_used_value(block_container_block_size))
- },
- };
-
- let max_block_size = match fragment.style.max_block_size() {
- MaxSize::None => None,
- MaxSize::LengthPercentage(ref lp) => lp.maybe_to_used_value(block_container_block_size),
- };
+ let block_size = MaybeAuto::from_option(
+ fragment
+ .style
+ .content_block_size()
+ .maybe_to_used_value(block_container_block_size),
+ );
- let min_block_size = match fragment.style.min_block_size() {
- Size::Auto => MaybeAuto::Auto,
- Size::LengthPercentage(ref lp) => {
- MaybeAuto::from_option(lp.maybe_to_used_value(block_container_block_size))
- },
- }
+ let max_block_size = fragment
+ .style
+ .max_block_size()
+ .maybe_to_used_value(block_container_block_size);
+
+ let min_block_size = MaybeAuto::from_option(
+ fragment
+ .style
+ .min_block_size()
+ .maybe_to_used_value(block_container_block_size),
+ )
.specified_or_zero();
// If the style includes `box-sizing: border-box`, subtract the border and padding.
@@ -1402,7 +1402,8 @@ impl BlockFlow {
let content_block_size = self.fragment.style().content_block_size();
match content_block_size {
- Size::Auto => {
+ Size::LengthPercentage(ref lp) => lp.maybe_to_used_value(containing_block_size),
+ _ => {
let container_size = containing_block_size?;
let (block_start, block_end) = {
let position = self.fragment.style().logical_position();
@@ -1437,7 +1438,6 @@ impl BlockFlow {
(_, _) => None,
}
},
- Size::LengthPercentage(ref lp) => lp.maybe_to_used_value(containing_block_size),
}
}
@@ -2167,10 +2167,13 @@ impl Flow for BlockFlow {
// If this block has a fixed width, just use that for the minimum and preferred width,
// rather than bubbling up children inline width.
// FIXME(emilio): This should probably be writing-mode-aware.
- let consult_children = match self.fragment.style().get_position().width {
- Size::Auto => true,
- Size::LengthPercentage(ref lp) => lp.maybe_to_used_value(None).is_none(),
- };
+ let consult_children = self
+ .fragment
+ .style()
+ .get_position()
+ .width
+ .maybe_to_used_value(None)
+ .is_none();
self.bubble_inline_sizes_for_block(consult_children);
self.fragment
.restyle_damage
diff --git a/components/layout/flex.rs b/components/layout/flex.rs
index 76df1f1ce0e..f2aa96a0ec9 100644
--- a/components/layout/flex.rs
+++ b/components/layout/flex.rs
@@ -48,11 +48,11 @@ impl AxisSize {
/// containing block size, min constraint, and max constraint
pub fn new(size: &Size, content_size: Option<Au>, min: &Size, max: &MaxSize) -> AxisSize {
match size {
- Size::Auto => AxisSize::MinMax(SizeConstraint::new(content_size, min, max, None)),
Size::LengthPercentage(ref lp) => match lp.maybe_to_used_value(content_size) {
Some(length) => AxisSize::Definite(length),
None => AxisSize::Infinite,
},
+ _ => AxisSize::MinMax(SizeConstraint::new(content_size, min, max, None)),
}
}
}
@@ -72,10 +72,7 @@ fn from_flex_basis(flex_basis: &FlexBasis, main_length: &Size, containing_length
_ => width,
};
- match width {
- Size::Auto => MaybeAuto::Auto,
- Size::LengthPercentage(ref lp) => MaybeAuto::Specified(lp.to_used_value(containing_length)),
- }
+ MaybeAuto::from_option(width.to_used_value(containing_length))
}
/// Represents a child in a flex container. Most fields here are used in
diff --git a/components/layout/floats.rs b/components/layout/floats.rs
index 055d883e28c..4781e72aa1f 100644
--- a/components/layout/floats.rs
+++ b/components/layout/floats.rs
@@ -10,7 +10,6 @@ use log::debug;
use serde::Serialize;
use style::computed_values::float::T as StyleFloat;
use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
-use style::values::computed::Size;
use crate::block::FormattingContextType;
use crate::flow::{Flow, FlowFlags, GetBaseFlow, ImmutableFlowUtils};
@@ -551,12 +550,8 @@ impl SpeculatedFloatPlacement {
// traversal logic will know that objects later in the document
// might flow around this float.
let inline_size = flow.as_block().fragment.style.content_inline_size();
- let fixed = match inline_size {
- Size::Auto => false,
- Size::LengthPercentage(ref lp) => {
- lp.0.is_definitely_zero() || lp.0.maybe_to_used_value(None).is_some()
- },
- };
+ let fixed =
+ inline_size.is_definitely_zero() || inline_size.maybe_to_used_value(None).is_some();
if !fixed {
float_inline_size = Au::from_px(1)
}
diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs
index 15bbf32b59e..444323154f1 100644
--- a/components/layout/fragment.rs
+++ b/components/layout/fragment.rs
@@ -50,7 +50,7 @@ use style::selector_parser::RestyleDamage;
use style::servo::restyle_damage::ServoRestyleDamage;
use style::str::char_is_whitespace;
use style::values::computed::counters::ContentItem;
-use style::values::computed::{Length, Size, VerticalAlign};
+use style::values::computed::{Length, VerticalAlign};
use style::values::generics::box_::{Perspective, VerticalAlignKeyword};
use style::values::generics::transform;
use webrender_api::units::LayoutTransform;
@@ -1642,11 +1642,7 @@ impl Fragment {
SpecificFragmentInfo::Canvas(_) |
SpecificFragmentInfo::Iframe(_) |
SpecificFragmentInfo::Svg(_) => {
- let inline_size = match self.style.content_inline_size() {
- Size::Auto => None,
- Size::LengthPercentage(ref lp) => lp.maybe_to_used_value(None),
- };
-
+ let inline_size = self.style.content_inline_size().maybe_to_used_value(None);
let mut inline_size = inline_size.unwrap_or_else(|| {
// We have to initialize the `border_padding` field first to make
// the size constraints work properly.
diff --git a/components/layout/model.rs b/components/layout/model.rs
index ee6d9e334c8..83b3e3a8879 100644
--- a/components/layout/model.rs
+++ b/components/layout/model.rs
@@ -147,14 +147,12 @@ impl MarginCollapseInfo {
) -> (CollapsibleMargins, Au) {
let state = match self.state {
MarginCollapseState::AccumulatingCollapsibleTopMargin => {
+ let content_block_size = fragment.style().content_block_size();
may_collapse_through = may_collapse_through &&
- match fragment.style().content_block_size() {
- Size::Auto => true,
- Size::LengthPercentage(ref lp) => {
- lp.is_definitely_zero() ||
- lp.maybe_to_used_value(containing_block_size).is_none()
- },
- };
+ content_block_size.is_definitely_zero() ||
+ content_block_size
+ .maybe_to_used_value(containing_block_size)
+ .is_none();
if may_collapse_through {
if fragment.style.min_block_size().is_auto() ||
@@ -522,12 +520,7 @@ impl MaybeAuto {
///
/// `style_length`: content size as given in the CSS.
pub fn style_length(style_length: &Size, container_size: Option<Au>) -> MaybeAuto {
- match style_length {
- Size::Auto => MaybeAuto::Auto,
- Size::LengthPercentage(ref lp) => {
- MaybeAuto::from_option(lp.0.maybe_to_used_value(container_size))
- },
- }
+ MaybeAuto::from_option(style_length.maybe_to_used_value(container_size))
}
#[inline]
@@ -595,17 +588,10 @@ impl SizeConstraint {
max_size: &MaxSize,
border: Option<Au>,
) -> SizeConstraint {
- let mut min_size = match min_size {
- Size::Auto => Au(0),
- Size::LengthPercentage(ref lp) => {
- lp.maybe_to_used_value(container_size).unwrap_or(Au(0))
- },
- };
-
- let mut max_size = match max_size {
- MaxSize::None => None,
- MaxSize::LengthPercentage(ref lp) => lp.maybe_to_used_value(container_size),
- };
+ let mut min_size = min_size
+ .maybe_to_used_value(container_size)
+ .unwrap_or(Au(0));
+ let mut max_size = max_size.maybe_to_used_value(container_size);
// Make sure max size is not smaller than min size.
max_size = max_size.map(|x| max(x, min_size));
diff --git a/components/layout/multicol.rs b/components/layout/multicol.rs
index ed82b41fe1c..b143c1215ca 100644
--- a/components/layout/multicol.rs
+++ b/components/layout/multicol.rs
@@ -15,7 +15,7 @@ use log::{debug, trace};
use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues;
use style::values::computed::length::{
- MaxSize, NonNegativeLengthOrAuto, NonNegativeLengthPercentageOrNormal, Size,
+ NonNegativeLengthOrAuto, NonNegativeLengthPercentageOrNormal,
};
use style::values::generics::column::ColumnCount;
@@ -167,14 +167,10 @@ impl Flow for MulticolFlow {
this_fragment_is_empty: true,
available_block_size: {
let style = &self.block_flow.fragment.style;
- let size = match style.content_block_size() {
- Size::Auto => None,
- Size::LengthPercentage(ref lp) => lp.maybe_to_used_value(None),
- };
- let size = size.or_else(|| match style.max_block_size() {
- MaxSize::None => None,
- MaxSize::LengthPercentage(ref lp) => lp.maybe_to_used_value(None),
- });
+ let size = style
+ .content_block_size()
+ .maybe_to_used_value(None)
+ .or_else(|| style.max_block_size().maybe_to_used_value(None));
size.unwrap_or_else(|| {
// FIXME: do column balancing instead
diff --git a/components/layout/table.rs b/components/layout/table.rs
index cc257c854f5..3f652d71051 100644
--- a/components/layout/table.rs
+++ b/components/layout/table.rs
@@ -307,17 +307,14 @@ impl Flow for TableFlow {
for specified_inline_size in &kid.as_mut_table_colgroup().inline_sizes {
self.column_intrinsic_inline_sizes
.push(ColumnIntrinsicInlineSize {
- minimum_length: match *specified_inline_size {
- Size::Auto => Au(0),
- Size::LengthPercentage(ref lp) => {
- lp.maybe_to_used_value(None).unwrap_or(Au(0))
- },
- },
+ minimum_length: specified_inline_size
+ .maybe_to_used_value(None)
+ .unwrap_or(Au(0)),
percentage: match *specified_inline_size {
- Size::Auto => 0.0,
Size::LengthPercentage(ref lp) => {
lp.0.to_percentage().map_or(0.0, |p| p.0)
},
+ _ => 0.0,
},
preferred: Au(0),
constrained: false,
diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs
index a70ea183931..0faeb8c1c6e 100644
--- a/components/layout/table_cell.rs
+++ b/components/layout/table_cell.rs
@@ -14,7 +14,6 @@ use script_layout_interface::wrapper_traits::ThreadSafeLayoutNode;
use serde::Serialize;
use style::logical_geometry::{LogicalMargin, LogicalRect, LogicalSize, WritingMode};
use style::properties::ComputedValues;
-use style::values::computed::length::Size;
use style::values::computed::Color;
use style::values::generics::box_::{VerticalAlign, VerticalAlignKeyword};
use style::values::specified::BorderStyle;
@@ -206,10 +205,13 @@ impl Flow for TableCellFlow {
);
self.block_flow.bubble_inline_sizes_for_block(true);
- let specified_inline_size = match self.block_flow.fragment.style().content_inline_size() {
- Size::Auto => Au(0),
- Size::LengthPercentage(ref lp) => lp.to_used_value(Au(0)),
- };
+ let specified_inline_size = self
+ .block_flow
+ .fragment
+ .style()
+ .content_inline_size()
+ .to_used_value(Au(0))
+ .unwrap_or(Au(0));
if self
.block_flow
diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs
index 49ff3f2b5c1..246e3a7bdd1 100644
--- a/components/layout/table_row.rs
+++ b/components/layout/table_row.rs
@@ -432,21 +432,17 @@ impl Flow for TableRowFlow {
// Collect minimum and preferred inline-sizes of the cell for automatic table layout
// calculation.
let child_base = kid.mut_base();
+ let resolved_child_specified_inline_size =
+ child_specified_inline_size.maybe_to_used_value(None);
let child_column_inline_size = ColumnIntrinsicInlineSize {
- minimum_length: match child_specified_inline_size {
- Size::Auto => None,
- Size::LengthPercentage(ref lp) => lp.0.maybe_to_used_value(None),
- }
- .unwrap_or(child_base.intrinsic_inline_sizes.minimum_inline_size),
+ minimum_length: resolved_child_specified_inline_size
+ .unwrap_or(child_base.intrinsic_inline_sizes.minimum_inline_size),
percentage: match child_specified_inline_size {
- Size::Auto => 0.0,
Size::LengthPercentage(ref lp) => lp.0.to_percentage().map_or(0.0, |p| p.0),
+ _ => 0.0,
},
preferred: child_base.intrinsic_inline_sizes.preferred_inline_size,
- constrained: match child_specified_inline_size {
- Size::Auto => false,
- Size::LengthPercentage(ref lp) => lp.0.maybe_to_used_value(None).is_some(),
- },
+ constrained: resolved_child_specified_inline_size.is_some(),
};
min_inline_size += child_column_inline_size.minimum_length;
pref_inline_size += child_column_inline_size.preferred;
diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs
index 26ff771e61b..3072b8f8573 100644
--- a/components/layout/table_wrapper.rs
+++ b/components/layout/table_wrapper.rs
@@ -848,25 +848,30 @@ fn initial_computed_inline_size(
preferred_width_of_all_columns: Au,
table_border_padding: Au,
) -> MaybeAuto {
- match block.fragment.style.content_inline_size() {
- Size::Auto => {
- if preferred_width_of_all_columns + table_border_padding <= containing_block_inline_size
- {
- MaybeAuto::Specified(preferred_width_of_all_columns + table_border_padding)
- } else if minimum_width_of_all_columns > containing_block_inline_size {
- MaybeAuto::Specified(minimum_width_of_all_columns)
- } else {
- MaybeAuto::Auto
- }
- },
- Size::LengthPercentage(ref lp) => {
- let used = lp.to_used_value(containing_block_inline_size);
- MaybeAuto::Specified(max(
- used - table_border_padding,
- minimum_width_of_all_columns,
- ))
- },
- }
+ block
+ .fragment
+ .style
+ .content_inline_size()
+ .to_used_value(containing_block_inline_size)
+ .map_or_else(
+ || {
+ if preferred_width_of_all_columns + table_border_padding <=
+ containing_block_inline_size
+ {
+ MaybeAuto::Specified(preferred_width_of_all_columns + table_border_padding)
+ } else if minimum_width_of_all_columns > containing_block_inline_size {
+ MaybeAuto::Specified(minimum_width_of_all_columns)
+ } else {
+ MaybeAuto::Auto
+ }
+ },
+ |used| {
+ MaybeAuto::Specified(max(
+ used - table_border_padding,
+ minimum_width_of_all_columns,
+ ))
+ },
+ )
}
struct Table {