mirror of
https://github.com/servo/servo.git
synced 2025-07-23 23:33:43 +01:00
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>
This commit is contained in:
parent
4bde9af515
commit
9597390d2b
66 changed files with 120 additions and 2798 deletions
|
@ -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 block_size = MaybeAuto::from_option(
|
||||
fragment
|
||||
.style
|
||||
.content_block_size()
|
||||
.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 max_block_size = fragment
|
||||
.style
|
||||
.max_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 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue