layout: Allow layouts to customize their used style (#35012)

Some layouts like table need some style overrides. We were handling this
in `ComputedValuesExt`, but it was messy, unreliable and too limited.

For example, we were assuming that a style with `display: table` would
belong to a table wrapper box or table grid box. However, certain HTML
elements can ignore their `display` value and generate a different kind
of box. I think we aren't doing that yet, but we will need this.

Also, resolving the used border of a table needs layout information,
which we don't have in `ComputedValuesExt`. This patch will allow to
improve border collapsing in a follow-up.

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Oriol Brufau 2025-01-16 08:54:47 -08:00 committed by GitHub
parent 7e7792dfbd
commit 60dc3b26fb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 368 additions and 238 deletions

View file

@ -42,7 +42,8 @@ use crate::sizing::{
ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult, IntrinsicSizingMode, ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult, IntrinsicSizingMode,
}; };
use crate::style_ext::{ use crate::style_ext::{
AspectRatio, Clamp, ComputedValuesExt, ContentBoxSizesAndPBMDeprecated, PaddingBorderMargin, AspectRatio, Clamp, ComputedValuesExt, ContentBoxSizesAndPBMDeprecated, LayoutStyle,
PaddingBorderMargin,
}; };
use crate::{ use crate::{
ConstraintSpace, ContainingBlock, ContainingBlockSize, IndefiniteContainingBlock, ConstraintSpace, ContainingBlock, ContainingBlockSize, IndefiniteContainingBlock,
@ -1052,7 +1053,7 @@ impl FlexContainer {
containing_block_for_container: &ContainingBlock, containing_block_for_container: &ContainingBlock,
) -> (FlexRelativeVec2<Au>, FlexRelativeVec2<Option<Au>>, bool) { ) -> (FlexRelativeVec2<Au>, FlexRelativeVec2<Option<Au>>, bool) {
let sizes: ContentBoxSizesAndPBMDeprecated = self let sizes: ContentBoxSizesAndPBMDeprecated = self
.style .layout_style()
.content_box_sizes_and_padding_border_margin(&containing_block_for_container.into()) .content_box_sizes_and_padding_border_margin(&containing_block_for_container.into())
.into(); .into();
@ -1071,6 +1072,11 @@ impl FlexContainer {
sizes.depends_on_block_constraints, sizes.depends_on_block_constraints,
) )
} }
#[inline]
pub(crate) fn layout_style(&self) -> LayoutStyle {
LayoutStyle::Default(&self.style)
}
} }
/// Align all flex lines per `align-content` according to /// Align all flex lines per `align-content` according to
@ -1141,7 +1147,8 @@ impl<'a> FlexItem<'a> {
pbm, pbm,
depends_on_block_constraints, depends_on_block_constraints,
} = box_ } = box_
.style() .independent_formatting_context
.layout_style()
.content_box_sizes_and_padding_border_margin(&containing_block.into()) .content_box_sizes_and_padding_border_margin(&containing_block.into())
.into(); .into();
@ -2281,7 +2288,9 @@ impl FlexItemBox {
content_max_box_size, content_max_box_size,
pbm, pbm,
.. ..
} = style } = self
.independent_formatting_context
.layout_style()
.content_box_sizes_and_padding_border_margin(containing_block) .content_box_sizes_and_padding_border_margin(containing_block)
.into(); .into();
let preferred_aspect_ratio = self let preferred_aspect_ratio = self

View file

@ -15,7 +15,7 @@ use crate::context::LayoutContext;
use crate::dom::NodeExt; use crate::dom::NodeExt;
use crate::dom_traversal::NodeAndStyleInfo; use crate::dom_traversal::NodeAndStyleInfo;
use crate::fragment_tree::BaseFragmentInfo; use crate::fragment_tree::BaseFragmentInfo;
use crate::style_ext::{ComputedValuesExt, PaddingBorderMargin}; use crate::style_ext::{LayoutStyle, PaddingBorderMargin};
use crate::ContainingBlock; use crate::ContainingBlock;
#[derive(Debug)] #[derive(Debug)]
@ -52,6 +52,11 @@ impl InlineBox {
..*self ..*self
} }
} }
#[inline]
pub(crate) fn layout_style(&self) -> LayoutStyle {
LayoutStyle::Default(&self.style)
}
} }
#[derive(Debug, Default)] #[derive(Debug, Default)]
@ -214,7 +219,9 @@ impl InlineBoxContainerState {
font_metrics: Option<&FontMetrics>, font_metrics: Option<&FontMetrics>,
) -> Self { ) -> Self {
let style = inline_box.style.clone(); let style = inline_box.style.clone();
let pbm = style.padding_border_margin(containing_block); let pbm = inline_box
.layout_style()
.padding_border_margin(containing_block);
let mut flags = InlineContainerStateFlags::empty(); let mut flags = InlineContainerStateFlags::empty();
if inline_container_needs_strut(&style, layout_context, Some(&pbm)) { if inline_container_needs_strut(&style, layout_context, Some(&pbm)) {

View file

@ -2244,11 +2244,11 @@ impl<'layout_data> ContentSizesComputation<'layout_data> {
let inline_box = inline_box.borrow(); let inline_box = inline_box.borrow();
let zero = Au::zero(); let zero = Au::zero();
let writing_mode = self.constraint_space.writing_mode; let writing_mode = self.constraint_space.writing_mode;
let padding = inline_box let layout_style = inline_box.layout_style();
.style let padding = layout_style
.padding(writing_mode) .padding(writing_mode)
.percentages_relative_to(zero); .percentages_relative_to(zero);
let border = inline_box.style.border_width(writing_mode); let border = layout_style.border_width(writing_mode);
let margin = inline_box let margin = inline_box
.style .style
.margin(writing_mode) .margin(writing_mode)

View file

@ -38,7 +38,7 @@ use crate::layout_box_base::LayoutBoxBase;
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext, PositioningContextLength}; use crate::positioned::{AbsolutelyPositionedBox, PositioningContext, PositioningContextLength};
use crate::replaced::ReplacedContents; use crate::replaced::ReplacedContents;
use crate::sizing::{self, ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult}; use crate::sizing::{self, ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
use crate::style_ext::{ComputedValuesExt, ContentBoxSizesAndPBM, PaddingBorderMargin}; use crate::style_ext::{ContentBoxSizesAndPBM, LayoutStyle, PaddingBorderMargin};
use crate::{ use crate::{
ConstraintSpace, ContainingBlock, ContainingBlockSize, IndefiniteContainingBlock, ConstraintSpace, ContainingBlock, ContainingBlockSize, IndefiniteContainingBlock,
SizeConstraint, SizeConstraint,
@ -105,19 +105,22 @@ impl BlockLevelBox {
collected_margin: &mut CollapsedMargin, collected_margin: &mut CollapsedMargin,
containing_block: &ContainingBlock, containing_block: &ContainingBlock,
) -> bool { ) -> bool {
let style = match self { let layout_style = match self {
BlockLevelBox::SameFormattingContextBlock { base, .. } => &base.style, BlockLevelBox::SameFormattingContextBlock { base, contents, .. } => {
contents.layout_style(base)
},
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(_) | BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(_) |
BlockLevelBox::OutOfFlowFloatBox(_) => return true, BlockLevelBox::OutOfFlowFloatBox(_) => return true,
BlockLevelBox::OutsideMarker(_) => return false, BlockLevelBox::OutsideMarker(_) => return false,
BlockLevelBox::Independent(ref context) => { BlockLevelBox::Independent(ref context) => {
// FIXME: If the element doesn't fit next to floats, it will get clearance. // FIXME: If the element doesn't fit next to floats, it will get clearance.
// In that case this should be returning false. // In that case this should be returning false.
context.style() context.layout_style()
}, },
}; };
// FIXME: This should only return false when 'clear' causes clearance. // FIXME: This should only return false when 'clear' causes clearance.
let style = layout_style.style();
if style.get_box().clear != StyleClear::None { if style.get_box().clear != StyleClear::None {
return false; return false;
} }
@ -126,7 +129,7 @@ impl BlockLevelBox {
content_box_sizes, content_box_sizes,
pbm, pbm,
.. ..
} = style.content_box_sizes_and_padding_border_margin(&containing_block.into()); } = layout_style.content_box_sizes_and_padding_border_margin(&containing_block.into());
let margin = pbm.margin.auto_is(Au::zero); let margin = pbm.margin.auto_is(Au::zero);
collected_margin.adjoin_assign(&CollapsedMargin::new(margin.block_start)); collected_margin.adjoin_assign(&CollapsedMargin::new(margin.block_start));
@ -310,9 +313,11 @@ impl OutsideMarker {
// TODO: This is the wrong containing block, as it should be the containing block of the // TODO: This is the wrong containing block, as it should be the containing block of the
// parent of this list item. What this means in practice is that the writing mode could be // parent of this list item. What this means in practice is that the writing mode could be
// wrong and padding defined as a percentage will be resolved incorrectly. // wrong and padding defined as a percentage will be resolved incorrectly.
let pbm_of_list_item = self //
.list_item_style() // TODO: This should use the LayoutStyle of the list item, not the default one. Currently
.padding_border_margin(containing_block); // they are the same, but this could change in the future.
let pbm_of_list_item =
LayoutStyle::Default(self.list_item_style()).padding_border_margin(containing_block);
let content_rect = LogicalRect { let content_rect = LogicalRect {
start_corner: LogicalVec2 { start_corner: LogicalVec2 {
inline: -max_inline_size - inline: -max_inline_size -
@ -387,6 +392,11 @@ impl BlockFormattingContext {
detailed_layout_info: None, detailed_layout_info: None,
} }
} }
#[inline]
pub(crate) fn layout_style<'a>(&self, base: &'a LayoutBoxBase) -> LayoutStyle<'a> {
LayoutStyle::Default(&base.style)
}
} }
/// Finds the min/max-content inline size of the block-level children of a block container. /// Finds the min/max-content inline size of the block-level children of a block container.
@ -425,7 +435,7 @@ fn compute_inline_content_sizes_for_block_level_boxes(
}, },
BlockLevelBox::SameFormattingContextBlock { base, contents, .. } => { BlockLevelBox::SameFormattingContextBlock { base, contents, .. } => {
let inline_content_sizes_result = sizing::outer_inline( let inline_content_sizes_result = sizing::outer_inline(
&base.style, &contents.layout_style(base),
containing_block, containing_block,
&LogicalVec2::zero(), &LogicalVec2::zero(),
false, /* auto_block_size_stretches_to_containing_block */ false, /* auto_block_size_stretches_to_containing_block */
@ -568,6 +578,11 @@ impl BlockContainer {
), ),
} }
} }
#[inline]
pub(crate) fn layout_style<'a>(&self, base: &'a LayoutBoxBase) -> LayoutStyle<'a> {
LayoutStyle::Default(&base.style)
}
} }
impl ComputeInlineContentSizes for BlockContainer { impl ComputeInlineContentSizes for BlockContainer {
@ -824,6 +839,7 @@ fn layout_in_flow_non_replaced_block_level_same_formatting_context(
collapsible_with_parent_start_margin: Option<CollapsibleWithParentStartMargin>, collapsible_with_parent_start_margin: Option<CollapsibleWithParentStartMargin>,
) -> BoxFragment { ) -> BoxFragment {
let style = &base.style; let style = &base.style;
let layout_style = contents.layout_style(base);
let containing_block_writing_mode = containing_block.style.writing_mode; let containing_block_writing_mode = containing_block.style.writing_mode;
let get_inline_content_sizes = |constraint_space: &ConstraintSpace| { let get_inline_content_sizes = |constraint_space: &ConstraintSpace| {
base.inline_content_sizes(layout_context, constraint_space, contents) base.inline_content_sizes(layout_context, constraint_space, contents)
@ -837,7 +853,7 @@ fn layout_in_flow_non_replaced_block_level_same_formatting_context(
available_block_size, available_block_size,
} = solve_containing_block_padding_and_border_for_in_flow_box( } = solve_containing_block_padding_and_border_for_in_flow_box(
containing_block, containing_block,
style, &layout_style,
get_inline_content_sizes, get_inline_content_sizes,
false, /* is_table */ false, /* is_table */
); );
@ -1071,6 +1087,7 @@ impl IndependentNonReplacedContents {
base.inline_content_sizes(layout_context, constraint_space, self) base.inline_content_sizes(layout_context, constraint_space, self)
.sizes .sizes
}; };
let layout_style = self.layout_style(base);
let ContainingBlockPaddingAndBorder { let ContainingBlockPaddingAndBorder {
containing_block: containing_block_for_children, containing_block: containing_block_for_children,
pbm, pbm,
@ -1079,7 +1096,7 @@ impl IndependentNonReplacedContents {
available_block_size, available_block_size,
} = solve_containing_block_padding_and_border_for_in_flow_box( } = solve_containing_block_padding_and_border_for_in_flow_box(
containing_block, containing_block,
&base.style, &layout_style,
get_inline_content_sizes, get_inline_content_sizes,
self.is_table(), self.is_table(),
); );
@ -1163,7 +1180,9 @@ impl IndependentNonReplacedContents {
content_box_sizes, content_box_sizes,
pbm, pbm,
depends_on_block_constraints, depends_on_block_constraints,
} = style.content_box_sizes_and_padding_border_margin(&containing_block.into()); } = self
.layout_style(base)
.content_box_sizes_and_padding_border_margin(&containing_block.into());
let (margin_block_start, margin_block_end) = let (margin_block_start, margin_block_end) =
solve_block_margins_for_in_flow_block_level(&pbm); solve_block_margins_for_in_flow_block_level(&pbm);
@ -1468,8 +1487,8 @@ impl ReplacedContents {
containing_block: &ContainingBlock, containing_block: &ContainingBlock,
mut sequential_layout_state: Option<&mut SequentialLayoutState>, mut sequential_layout_state: Option<&mut SequentialLayoutState>,
) -> BoxFragment { ) -> BoxFragment {
let content_box_sizes_and_pbm = base let content_box_sizes_and_pbm = self
.style .layout_style(base)
.content_box_sizes_and_padding_border_margin(&containing_block.into()); .content_box_sizes_and_padding_border_margin(&containing_block.into());
let pbm = &content_box_sizes_and_pbm.pbm; let pbm = &content_box_sizes_and_pbm.pbm;
let content_size = self.used_size_as_if_inline_element( let content_size = self.used_size_as_if_inline_element(
@ -1618,10 +1637,11 @@ struct ResolvedMargins {
/// inline size could then be incorrect. /// inline size could then be incorrect.
fn solve_containing_block_padding_and_border_for_in_flow_box<'a>( fn solve_containing_block_padding_and_border_for_in_flow_box<'a>(
containing_block: &ContainingBlock<'_>, containing_block: &ContainingBlock<'_>,
style: &'a Arc<ComputedValues>, layout_style: &'a LayoutStyle,
get_inline_content_sizes: impl FnOnce(&ConstraintSpace) -> ContentSizes, get_inline_content_sizes: impl FnOnce(&ConstraintSpace) -> ContentSizes,
is_table: bool, is_table: bool,
) -> ContainingBlockPaddingAndBorder<'a> { ) -> ContainingBlockPaddingAndBorder<'a> {
let style = layout_style.style();
if matches!(style.pseudo(), Some(PseudoElement::ServoAnonymousBox)) { if matches!(style.pseudo(), Some(PseudoElement::ServoAnonymousBox)) {
// <https://drafts.csswg.org/css2/#anonymous-block-level> // <https://drafts.csswg.org/css2/#anonymous-block-level>
// > Anonymous block boxes are ignored when resolving percentage values that would // > Anonymous block boxes are ignored when resolving percentage values that would
@ -1650,7 +1670,7 @@ fn solve_containing_block_padding_and_border_for_in_flow_box<'a>(
content_box_sizes, content_box_sizes,
pbm, pbm,
depends_on_block_constraints, depends_on_block_constraints,
} = style.content_box_sizes_and_padding_border_margin(&containing_block.into()); } = layout_style.content_box_sizes_and_padding_border_margin(&containing_block.into());
let margin = pbm.margin.auto_is(Au::zero); let margin = pbm.margin.auto_is(Au::zero);
let pbm_sums = pbm.padding + pbm.border + margin; let pbm_sums = pbm.padding + pbm.border + margin;
@ -2140,8 +2160,9 @@ impl IndependentFormattingContext {
) -> IndependentLayoutResult { ) -> IndependentLayoutResult {
let style = self.style(); let style = self.style();
let container_writing_mode = containing_block.style.writing_mode; let container_writing_mode = containing_block.style.writing_mode;
let content_box_sizes_and_pbm = let content_box_sizes_and_pbm = self
style.content_box_sizes_and_padding_border_margin(&containing_block.into()); .layout_style()
.content_box_sizes_and_padding_border_margin(&containing_block.into());
let pbm = &content_box_sizes_and_pbm.pbm; let pbm = &content_box_sizes_and_pbm.pbm;
let margin = pbm.margin.auto_is(Au::zero); let margin = pbm.margin.auto_is(Au::zero);
let pbm_sums = pbm.padding + pbm.border + margin; let pbm_sums = pbm.padding + pbm.border + margin;

View file

@ -21,7 +21,7 @@ use crate::layout_box_base::LayoutBoxBase;
use crate::positioned::PositioningContext; use crate::positioned::PositioningContext;
use crate::replaced::ReplacedContents; use crate::replaced::ReplacedContents;
use crate::sizing::{self, ComputeInlineContentSizes, InlineContentSizesResult}; use crate::sizing::{self, ComputeInlineContentSizes, InlineContentSizesResult};
use crate::style_ext::{AspectRatio, DisplayInside}; use crate::style_ext::{AspectRatio, DisplayInside, LayoutStyle};
use crate::table::Table; use crate::table::Table;
use crate::taffy::TaffyContainer; use crate::taffy::TaffyContainer;
use crate::{ConstraintSpace, ContainingBlock, IndefiniteContainingBlock, LogicalVec2}; use crate::{ConstraintSpace, ContainingBlock, IndefiniteContainingBlock, LogicalVec2};
@ -217,7 +217,7 @@ impl IndependentFormattingContext {
auto_block_size_stretches_to_containing_block: bool, auto_block_size_stretches_to_containing_block: bool,
) -> InlineContentSizesResult { ) -> InlineContentSizesResult {
sizing::outer_inline( sizing::outer_inline(
self.style(), &self.layout_style(),
containing_block, containing_block,
auto_minimum, auto_minimum,
auto_block_size_stretches_to_containing_block, auto_block_size_stretches_to_containing_block,
@ -242,6 +242,18 @@ impl IndependentFormattingContext {
}, },
} }
} }
#[inline]
pub(crate) fn layout_style(&self) -> LayoutStyle {
match &self.contents {
IndependentFormattingContextContents::NonReplaced(content) => {
content.layout_style(&self.base)
},
IndependentFormattingContextContents::Replaced(content) => {
content.layout_style(&self.base)
},
}
}
} }
impl IndependentNonReplacedContents { impl IndependentNonReplacedContents {
@ -279,6 +291,16 @@ impl IndependentNonReplacedContents {
} }
} }
#[inline]
pub(crate) fn layout_style<'a>(&'a self, base: &'a LayoutBoxBase) -> LayoutStyle<'a> {
match self {
IndependentNonReplacedContents::Flow(fc) => fc.layout_style(base),
IndependentNonReplacedContents::Flex(fc) => fc.layout_style(),
IndependentNonReplacedContents::Grid(fc) => fc.layout_style(),
IndependentNonReplacedContents::Table(fc) => fc.layout_style(),
}
}
#[inline] #[inline]
pub(crate) fn preferred_aspect_ratio(&self) -> Option<AspectRatio> { pub(crate) fn preferred_aspect_ratio(&self) -> Option<AspectRatio> {
// TODO: support preferred aspect ratios on non-replaced boxes. // TODO: support preferred aspect ratios on non-replaced boxes.

View file

@ -467,7 +467,9 @@ impl HoistedAbsolutelyPositionedBox {
content_box_sizes, content_box_sizes,
pbm, pbm,
.. ..
} = style.content_box_sizes_and_padding_border_margin(&containing_block.into()); } = context
.layout_style()
.content_box_sizes_and_padding_border_margin(&containing_block.into());
let containing_block = &containing_block.into(); let containing_block = &containing_block.into();
let is_table = context.is_table(); let is_table = context.is_table();

View file

@ -31,8 +31,9 @@ use crate::context::LayoutContext;
use crate::dom::NodeExt; use crate::dom::NodeExt;
use crate::fragment_tree::{BaseFragmentInfo, Fragment, IFrameFragment, ImageFragment}; use crate::fragment_tree::{BaseFragmentInfo, Fragment, IFrameFragment, ImageFragment};
use crate::geom::{LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSize, Size, Sizes}; use crate::geom::{LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSize, Size, Sizes};
use crate::layout_box_base::LayoutBoxBase;
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult}; use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
use crate::style_ext::{AspectRatio, Clamp, ComputedValuesExt, ContentBoxSizesAndPBM}; use crate::style_ext::{AspectRatio, Clamp, ComputedValuesExt, ContentBoxSizesAndPBM, LayoutStyle};
use crate::{ConstraintSpace, ContainingBlock, SizeConstraint}; use crate::{ConstraintSpace, ContainingBlock, SizeConstraint};
#[derive(Debug)] #[derive(Debug)]
@ -567,6 +568,11 @@ impl ReplacedContents {
block: block_size, block: block_size,
} }
} }
#[inline]
pub(crate) fn layout_style<'a>(&self, base: &'a LayoutBoxBase) -> LayoutStyle<'a> {
LayoutStyle::Default(&base.style)
}
} }
impl ComputeInlineContentSizes for ReplacedContents { impl ComputeInlineContentSizes for ReplacedContents {

View file

@ -8,13 +8,12 @@ use std::cell::LazyCell;
use std::ops::{Add, AddAssign}; use std::ops::{Add, AddAssign};
use app_units::Au; use app_units::Au;
use style::properties::ComputedValues;
use style::values::computed::LengthPercentage; use style::values::computed::LengthPercentage;
use style::Zero; use style::Zero;
use crate::context::LayoutContext; use crate::context::LayoutContext;
use crate::geom::Size; use crate::geom::Size;
use crate::style_ext::{AspectRatio, Clamp, ComputedValuesExt, ContentBoxSizesAndPBM}; use crate::style_ext::{AspectRatio, Clamp, ComputedValuesExt, ContentBoxSizesAndPBM, LayoutStyle};
use crate::{ConstraintSpace, IndefiniteContainingBlock, LogicalVec2}; use crate::{ConstraintSpace, IndefiniteContainingBlock, LogicalVec2};
#[derive(PartialEq)] #[derive(PartialEq)]
@ -111,7 +110,7 @@ impl From<Au> for ContentSizes {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub(crate) fn outer_inline( pub(crate) fn outer_inline(
style: &ComputedValues, layout_style: &LayoutStyle,
containing_block: &IndefiniteContainingBlock, containing_block: &IndefiniteContainingBlock,
auto_minimum: &LogicalVec2<Au>, auto_minimum: &LogicalVec2<Au>,
auto_block_size_stretches_to_containing_block: bool, auto_block_size_stretches_to_containing_block: bool,
@ -125,12 +124,13 @@ pub(crate) fn outer_inline(
content_box_sizes, content_box_sizes,
pbm, pbm,
mut depends_on_block_constraints, mut depends_on_block_constraints,
} = style.content_box_sizes_and_padding_border_margin(containing_block); } = layout_style.content_box_sizes_and_padding_border_margin(containing_block);
let margin = pbm.margin.map(|v| v.auto_is(Au::zero)); let margin = pbm.margin.map(|v| v.auto_is(Au::zero));
let pbm_sums = LogicalVec2 { let pbm_sums = LogicalVec2 {
block: pbm.padding_border_sums.block + margin.block_sum(), block: pbm.padding_border_sums.block + margin.block_sum(),
inline: pbm.padding_border_sums.inline + margin.inline_sum(), inline: pbm.padding_border_sums.inline + margin.inline_sum(),
}; };
let style = layout_style.style();
let content_size = LazyCell::new(|| { let content_size = LazyCell::new(|| {
let constraint_space = if establishes_containing_block { let constraint_space = if establishes_containing_block {
let available_block_size = containing_block let available_block_size = containing_block

View file

@ -278,23 +278,10 @@ pub(crate) trait ComputedValuesExt {
box_size: LogicalVec2<Size<Au>>, box_size: LogicalVec2<Size<Au>>,
pbm: &PaddingBorderMargin, pbm: &PaddingBorderMargin,
) -> LogicalVec2<Size<Au>>; ) -> LogicalVec2<Size<Au>>;
fn content_box_sizes_and_padding_border_margin(
&self,
containing_block: &IndefiniteContainingBlock,
) -> ContentBoxSizesAndPBM;
fn padding_border_margin(&self, containing_block: &ContainingBlock) -> PaddingBorderMargin;
fn padding_border_margin_with_writing_mode_and_containing_block_inline_size(
&self,
writing_mode: WritingMode,
containing_block_inline_size: Au,
) -> PaddingBorderMargin;
fn padding(&self, containing_block_writing_mode: WritingMode)
-> LogicalSides<LengthPercentage>;
fn border_style_color( fn border_style_color(
&self, &self,
containing_block_writing_mode: WritingMode, containing_block_writing_mode: WritingMode,
) -> LogicalSides<BorderStyleColor>; ) -> LogicalSides<BorderStyleColor>;
fn border_width(&self, containing_block_writing_mode: WritingMode) -> LogicalSides<Au>;
fn physical_margin(&self) -> PhysicalSides<LengthPercentageOrAuto<'_>>; fn physical_margin(&self) -> PhysicalSides<LengthPercentageOrAuto<'_>>;
fn margin( fn margin(
&self, &self,
@ -445,129 +432,6 @@ impl ComputedValuesExt for ComputedValues {
} }
} }
fn content_box_sizes_and_padding_border_margin(
&self,
containing_block: &IndefiniteContainingBlock,
) -> ContentBoxSizesAndPBM {
// <https://drafts.csswg.org/css-sizing-3/#cyclic-percentage-contribution>
// If max size properties or preferred size properties are set to a value containing
// indefinite percentages, we treat the entire value as the initial value of the property.
// However, for min size properties, as well as for margins and paddings,
// we instead resolve indefinite percentages against zero.
let containing_block_size = containing_block.size.map(|value| value.non_auto());
let containing_block_size_auto_is_zero =
containing_block_size.map(|value| value.unwrap_or_else(Au::zero));
let writing_mode = containing_block.writing_mode;
let pbm = self.padding_border_margin_with_writing_mode_and_containing_block_inline_size(
writing_mode,
containing_block.size.inline.auto_is(Au::zero),
);
let box_size = self.box_size(writing_mode);
let min_size = self.min_box_size(writing_mode);
let max_size = self.max_box_size(writing_mode);
let depends_on_block_constraints = |size: &Size<LengthPercentage>| {
match size {
// fit-content is like clamp(min-content, stretch, max-content), but currently
// min-content and max-content have the same behavior in the block axis,
// so there is no dependency on block constraints.
// TODO: for flex and grid layout, min-content and max-content should be different.
// TODO: We are assuming that Size::Initial doesn't stretch. However, it may actually
// stretch flex and grid items depending on the CSS Align properties, in that case
// the caller needs to take care of it.
Size::Stretch => true,
Size::Numeric(length_percentage) => length_percentage.has_percentage(),
_ => false,
}
};
let depends_on_block_constraints = depends_on_block_constraints(&box_size.block) ||
depends_on_block_constraints(&min_size.block) ||
depends_on_block_constraints(&max_size.block) ||
self.depends_on_block_constraints_due_to_relative_positioning(writing_mode);
let box_size = box_size.maybe_percentages_relative_to_basis(&containing_block_size);
let content_box_size = self
.content_box_size_for_box_size(box_size, &pbm)
.map(|v| v.map(Au::from));
let min_size = min_size.percentages_relative_to_basis(&containing_block_size_auto_is_zero);
let content_min_box_size = self
.content_min_box_size_for_min_size(min_size, &pbm)
.map(|v| v.map(Au::from));
let max_size = max_size.maybe_percentages_relative_to_basis(&containing_block_size);
let content_max_box_size = self
.content_max_box_size_for_max_size(max_size, &pbm)
.map(|v| v.map(Au::from));
ContentBoxSizesAndPBM {
content_box_sizes: LogicalVec2 {
block: Sizes::new(
content_box_size.block,
content_min_box_size.block,
content_max_box_size.block,
),
inline: Sizes::new(
content_box_size.inline,
content_min_box_size.inline,
content_max_box_size.inline,
),
},
pbm,
depends_on_block_constraints,
}
}
fn padding_border_margin(&self, containing_block: &ContainingBlock) -> PaddingBorderMargin {
self.padding_border_margin_with_writing_mode_and_containing_block_inline_size(
containing_block.style.writing_mode,
containing_block.size.inline,
)
}
fn padding_border_margin_with_writing_mode_and_containing_block_inline_size(
&self,
writing_mode: WritingMode,
containing_block_inline_size: Au,
) -> PaddingBorderMargin {
let padding = self
.padding(writing_mode)
.percentages_relative_to(containing_block_inline_size);
let border = self.border_width(writing_mode);
let margin = self
.margin(writing_mode)
.percentages_relative_to(containing_block_inline_size);
PaddingBorderMargin {
padding_border_sums: LogicalVec2 {
inline: padding.inline_sum() + border.inline_sum(),
block: padding.block_sum() + border.block_sum(),
},
padding,
border,
margin,
}
}
fn padding(
&self,
containing_block_writing_mode: WritingMode,
) -> LogicalSides<LengthPercentage> {
if self.get_box().display.inside() == stylo::DisplayInside::Table &&
self.get_inherited_table().border_collapse == BorderCollapse::Collapse
{
// https://drafts.csswg.org/css-tables/#collapsed-style-overrides
// > The padding of the table-root is ignored (as if it was set to 0px).
return LogicalSides::zero();
}
let padding = self.get_padding().clone();
LogicalSides::from_physical(
&PhysicalSides::new(
padding.padding_top.0,
padding.padding_right.0,
padding.padding_bottom.0,
padding.padding_left.0,
),
containing_block_writing_mode,
)
}
fn border_style_color( fn border_style_color(
&self, &self,
containing_block_writing_mode: WritingMode, containing_block_writing_mode: WritingMode,
@ -578,36 +442,6 @@ impl ComputedValuesExt for ComputedValues {
) )
} }
fn border_width(&self, containing_block_writing_mode: WritingMode) -> LogicalSides<Au> {
let border = self.get_border();
if self.get_box().display.inside() == stylo::DisplayInside::Table &&
!matches!(self.pseudo(), Some(PseudoElement::ServoTableGrid)) &&
self.get_inherited_table().border_collapse == BorderCollapse::Collapse
{
// For tables in collapsed-borders mode we halve the border widths, because
// > in this model, the width of the table includes half the table border.
// https://www.w3.org/TR/CSS22/tables.html#collapsing-borders
return LogicalSides::from_physical(
&PhysicalSides::new(
border.border_top_width / 2,
border.border_right_width / 2,
border.border_bottom_width / 2,
border.border_left_width / 2,
),
containing_block_writing_mode,
);
}
LogicalSides::from_physical(
&PhysicalSides::new(
border.border_top_width,
border.border_right_width,
border.border_bottom_width,
border.border_left_width,
),
containing_block_writing_mode,
)
}
fn physical_margin(&self) -> PhysicalSides<LengthPercentageOrAuto<'_>> { fn physical_margin(&self) -> PhysicalSides<LengthPercentageOrAuto<'_>> {
fn convert(inset: &Margin) -> LengthPercentageOrAuto<'_> { fn convert(inset: &Margin) -> LengthPercentageOrAuto<'_> {
match inset { match inset {
@ -969,6 +803,183 @@ impl ComputedValuesExt for ComputedValues {
} }
} }
pub(crate) enum LayoutStyle<'a> {
Default(&'a ComputedValues),
Table(&'a ComputedValues),
}
impl LayoutStyle<'_> {
#[inline]
pub(crate) fn style(&self) -> &ComputedValues {
match self {
Self::Default(style) => style,
Self::Table(style) => style,
}
}
pub(crate) fn content_box_sizes_and_padding_border_margin(
&self,
containing_block: &IndefiniteContainingBlock,
) -> ContentBoxSizesAndPBM {
// <https://drafts.csswg.org/css-sizing-3/#cyclic-percentage-contribution>
// If max size properties or preferred size properties are set to a value containing
// indefinite percentages, we treat the entire value as the initial value of the property.
// However, for min size properties, as well as for margins and paddings,
// we instead resolve indefinite percentages against zero.
let containing_block_size = containing_block.size.map(|value| value.non_auto());
let containing_block_size_auto_is_zero =
containing_block_size.map(|value| value.unwrap_or_else(Au::zero));
let writing_mode = containing_block.writing_mode;
let pbm = self.padding_border_margin_with_writing_mode_and_containing_block_inline_size(
writing_mode,
containing_block.size.inline.auto_is(Au::zero),
);
let style = self.style();
let box_size = style.box_size(writing_mode);
let min_size = style.min_box_size(writing_mode);
let max_size = style.max_box_size(writing_mode);
let depends_on_block_constraints = |size: &Size<LengthPercentage>| {
match size {
// fit-content is like clamp(min-content, stretch, max-content), but currently
// min-content and max-content have the same behavior in the block axis,
// so there is no dependency on block constraints.
// TODO: for flex and grid layout, min-content and max-content should be different.
// TODO: We are assuming that Size::Initial doesn't stretch. However, it may actually
// stretch flex and grid items depending on the CSS Align properties, in that case
// the caller needs to take care of it.
Size::Stretch => true,
Size::Numeric(length_percentage) => length_percentage.has_percentage(),
_ => false,
}
};
let depends_on_block_constraints = depends_on_block_constraints(&box_size.block) ||
depends_on_block_constraints(&min_size.block) ||
depends_on_block_constraints(&max_size.block) ||
style.depends_on_block_constraints_due_to_relative_positioning(writing_mode);
let box_size = box_size.maybe_percentages_relative_to_basis(&containing_block_size);
let content_box_size = style
.content_box_size_for_box_size(box_size, &pbm)
.map(|v| v.map(Au::from));
let min_size = min_size.percentages_relative_to_basis(&containing_block_size_auto_is_zero);
let content_min_box_size = style
.content_min_box_size_for_min_size(min_size, &pbm)
.map(|v| v.map(Au::from));
let max_size = max_size.maybe_percentages_relative_to_basis(&containing_block_size);
let content_max_box_size = style
.content_max_box_size_for_max_size(max_size, &pbm)
.map(|v| v.map(Au::from));
ContentBoxSizesAndPBM {
content_box_sizes: LogicalVec2 {
block: Sizes::new(
content_box_size.block,
content_min_box_size.block,
content_max_box_size.block,
),
inline: Sizes::new(
content_box_size.inline,
content_min_box_size.inline,
content_max_box_size.inline,
),
},
pbm,
depends_on_block_constraints,
}
}
pub(crate) fn padding_border_margin(
&self,
containing_block: &ContainingBlock,
) -> PaddingBorderMargin {
self.padding_border_margin_with_writing_mode_and_containing_block_inline_size(
containing_block.style.writing_mode,
containing_block.size.inline,
)
}
pub(crate) fn padding_border_margin_with_writing_mode_and_containing_block_inline_size(
&self,
writing_mode: WritingMode,
containing_block_inline_size: Au,
) -> PaddingBorderMargin {
let padding = self
.padding(writing_mode)
.percentages_relative_to(containing_block_inline_size);
let style = self.style();
let border = self.border_width(writing_mode);
let margin = style
.margin(writing_mode)
.percentages_relative_to(containing_block_inline_size);
PaddingBorderMargin {
padding_border_sums: LogicalVec2 {
inline: padding.inline_sum() + border.inline_sum(),
block: padding.block_sum() + border.block_sum(),
},
padding,
border,
margin,
}
}
pub(crate) fn padding(
&self,
containing_block_writing_mode: WritingMode,
) -> LogicalSides<LengthPercentage> {
let style = self.style();
if matches!(self, Self::Table(_)) &&
style.get_inherited_table().border_collapse == BorderCollapse::Collapse
{
// https://drafts.csswg.org/css-tables/#collapsed-style-overrides
// > The padding of the table-root is ignored (as if it was set to 0px).
return LogicalSides::zero();
}
let padding = self.style().get_padding().clone();
LogicalSides::from_physical(
&PhysicalSides::new(
padding.padding_top.0,
padding.padding_right.0,
padding.padding_bottom.0,
padding.padding_left.0,
),
containing_block_writing_mode,
)
}
pub(crate) fn border_width(
&self,
containing_block_writing_mode: WritingMode,
) -> LogicalSides<Au> {
let style = self.style();
let border = style.get_border();
if matches!(self, Self::Table(_)) &&
style.get_inherited_table().border_collapse == BorderCollapse::Collapse
{
// For tables in collapsed-borders mode we halve the border widths, because
// > in this model, the width of the table includes half the table border.
// https://www.w3.org/TR/CSS22/tables.html#collapsing-borders
return LogicalSides::from_physical(
&PhysicalSides::new(
border.border_top_width / 2,
border.border_right_width / 2,
border.border_bottom_width / 2,
border.border_left_width / 2,
),
containing_block_writing_mode,
);
}
LogicalSides::from_physical(
&PhysicalSides::new(
border.border_top_width,
border.border_right_width,
border.border_bottom_width,
border.border_left_width,
),
containing_block_writing_mode,
)
}
}
impl From<stylo::Display> for Display { impl From<stylo::Display> for Display {
fn from(packed: stylo::Display) -> Self { fn from(packed: stylo::Display) -> Self {
let outside = packed.outside(); let outside = packed.outside();

View file

@ -38,7 +38,9 @@ use crate::geom::{
}; };
use crate::positioned::{relative_adjustement, PositioningContext, PositioningContextLength}; use crate::positioned::{relative_adjustement, PositioningContext, PositioningContextLength};
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult}; use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
use crate::style_ext::{BorderStyleColor, Clamp, ComputedValuesExt, PaddingBorderMargin}; use crate::style_ext::{
BorderStyleColor, Clamp, ComputedValuesExt, LayoutStyle, PaddingBorderMargin,
};
use crate::table::{SpecificTableOrTableCellInfo, TableSlotCoordinates}; use crate::table::{SpecificTableOrTableCellInfo, TableSlotCoordinates};
use crate::{ use crate::{
ConstraintSpace, ContainingBlock, ContainingBlockSize, IndefiniteContainingBlock, WritingMode, ConstraintSpace, ContainingBlock, ContainingBlockSize, IndefiniteContainingBlock, WritingMode,
@ -121,9 +123,12 @@ impl CollapsedBorder {
Self { style_color, width } Self { style_color, width }
} }
fn from_style(style: &ComputedValues, writing_mode: WritingMode) -> LogicalSides<Self> { fn from_layout_style(
let border_style_color = style.border_style_color(writing_mode); layout_style: &LayoutStyle,
let border_width = style.border_width(writing_mode); writing_mode: WritingMode,
) -> LogicalSides<Self> {
let border_style_color = layout_style.style().border_style_color(writing_mode);
let border_width = layout_style.border_width(writing_mode);
LogicalSides { LogicalSides {
inline_start: Self::new(border_style_color.inline_start, border_width.inline_start), inline_start: Self::new(border_style_color.inline_start, border_width.inline_start),
inline_end: Self::new(border_style_color.inline_end, border_width.inline_end), inline_end: Self::new(border_style_color.inline_end, border_width.inline_end),
@ -285,12 +290,10 @@ impl<'a> TableLayout<'a> {
_ => continue, _ => continue,
}; };
let padding = cell let layout_style = cell.layout_style();
.base let padding = layout_style
.style
.padding(writing_mode) .padding(writing_mode)
.percentages_relative_to(Au::zero()); .percentages_relative_to(Au::zero());
let border = self let border = self
.get_collapsed_border_widths_for_area(LogicalSides { .get_collapsed_border_widths_for_area(LogicalSides {
inline_start: column_index, inline_start: column_index,
@ -298,7 +301,7 @@ impl<'a> TableLayout<'a> {
block_start: row_index, block_start: row_index,
block_end: row_index + cell.rowspan, block_end: row_index + cell.rowspan,
}) })
.unwrap_or_else(|| cell.base.style.border_width(writing_mode)); .unwrap_or_else(|| layout_style.border_width(writing_mode));
let padding_border_sums = LogicalVec2 { let padding_border_sums = LogicalVec2 {
inline: padding.inline_sum() + border.inline_sum(), inline: padding.inline_sum() + border.inline_sum(),
@ -1217,16 +1220,14 @@ impl<'a> TableLayout<'a> {
self.get_collapsed_border_style_colors_for_area(area), self.get_collapsed_border_style_colors_for_area(area),
self.table.style.writing_mode, self.table.style.writing_mode,
); );
let layout_style = cell.layout_style();
let border = self let border = self
.get_collapsed_border_widths_for_area(area) .get_collapsed_border_widths_for_area(area)
.unwrap_or_else(|| { .unwrap_or_else(|| {
cell.base layout_style
.style
.border_width(containing_block_for_table.style.writing_mode) .border_width(containing_block_for_table.style.writing_mode)
}); });
let padding: LogicalSides<Au> = cell let padding: LogicalSides<Au> = layout_style
.base
.style
.padding(containing_block_for_table.style.writing_mode) .padding(containing_block_for_table.style.writing_mode)
.percentages_relative_to(self.basis_for_cell_padding_percentage); .percentages_relative_to(self.basis_for_cell_padding_percentage);
let inline_border_padding_sum = border.inline_sum() + padding.inline_sum(); let inline_border_padding_sum = border.inline_sum() + padding.inline_sum();
@ -1651,9 +1652,8 @@ impl<'a> TableLayout<'a> {
containing_block_for_table: &ContainingBlock, containing_block_for_table: &ContainingBlock,
) -> IndependentLayout { ) -> IndependentLayout {
let table_writing_mode = containing_block_for_children.style.writing_mode; let table_writing_mode = containing_block_for_children.style.writing_mode;
self.pbm = self let layout_style = self.table.layout_style();
.table self.pbm = layout_style
.style
.padding_border_margin_with_writing_mode_and_containing_block_inline_size( .padding_border_margin_with_writing_mode_and_containing_block_inline_size(
table_writing_mode, table_writing_mode,
containing_block_for_table.size.inline, containing_block_for_table.size.inline,
@ -1690,9 +1690,7 @@ impl<'a> TableLayout<'a> {
let offset_from_wrapper = -self.pbm.padding - self.pbm.border; let offset_from_wrapper = -self.pbm.padding - self.pbm.border;
let mut current_block_offset = offset_from_wrapper.block_start; let mut current_block_offset = offset_from_wrapper.block_start;
let depends_on_block_constraints = self let depends_on_block_constraints = layout_style
.table
.style
.content_box_sizes_and_padding_border_margin(&containing_block_for_table.into()) .content_box_sizes_and_padding_border_margin(&containing_block_for_table.into())
.depends_on_block_constraints; .depends_on_block_constraints;
@ -2234,8 +2232,8 @@ impl<'a> TableLayout<'a> {
}; };
let mut apply_border = let mut apply_border =
|style: &ComputedValues, block: &Range<usize>, inline: &Range<usize>| { |layout_style: &LayoutStyle, block: &Range<usize>, inline: &Range<usize>| {
let border = CollapsedBorder::from_style(style, writing_mode); let border = CollapsedBorder::from_layout_style(layout_style, writing_mode);
collapsed_borders.block[block.start].max_assign(&border.block_start, inline); collapsed_borders.block[block.start].max_assign(&border.block_start, inline);
collapsed_borders.block[block.end].max_assign(&border.block_end, inline); collapsed_borders.block[block.end].max_assign(&border.block_end, inline);
collapsed_borders.inline[inline.start].max_assign(&border.inline_start, block); collapsed_borders.inline[inline.start].max_assign(&border.inline_start, block);
@ -2243,18 +2241,34 @@ impl<'a> TableLayout<'a> {
}; };
let all_rows = 0..self.table.size.height; let all_rows = 0..self.table.size.height;
let all_columns = 0..self.table.size.width; let all_columns = 0..self.table.size.width;
apply_border(&self.table.grid_style, &all_rows, &all_columns); apply_border(&self.table.layout_style_for_grid(), &all_rows, &all_columns);
for column_group in &self.table.column_groups { for column_group in &self.table.column_groups {
apply_border(&column_group.style, &all_rows, &column_group.track_range); apply_border(
&column_group.layout_style(),
&all_rows,
&column_group.track_range,
);
} }
for (column_index, column) in self.table.columns.iter().enumerate() { for (column_index, column) in self.table.columns.iter().enumerate() {
apply_border(&column.style, &all_rows, &(column_index..column_index + 1)); apply_border(
&column.layout_style(),
&all_rows,
&(column_index..column_index + 1),
);
} }
for row_group in &self.table.row_groups { for row_group in &self.table.row_groups {
apply_border(&row_group.style, &row_group.track_range, &all_columns); apply_border(
&row_group.layout_style(),
&row_group.track_range,
&all_columns,
);
} }
for (row_index, row) in self.table.rows.iter().enumerate() { for (row_index, row) in self.table.rows.iter().enumerate() {
apply_border(&row.style, &(row_index..row_index + 1), &all_columns); apply_border(
&row.layout_style(),
&(row_index..row_index + 1),
&all_columns,
);
} }
for row_index in 0..self.table.size.height { for row_index in 0..self.table.size.height {
for column_index in 0..self.table.size.width { for column_index in 0..self.table.size.width {
@ -2264,7 +2278,7 @@ impl<'a> TableLayout<'a> {
}; };
apply_border( apply_border(
&cell.base.style, &cell.layout_style(),
&(row_index..row_index + cell.rowspan), &(row_index..row_index + cell.rowspan),
&(column_index..column_index + cell.colspan), &(column_index..column_index + cell.colspan),
); );
@ -2752,9 +2766,9 @@ impl ComputeInlineContentSizes for Table {
constraint_space: &ConstraintSpace, constraint_space: &ConstraintSpace,
) -> InlineContentSizesResult { ) -> InlineContentSizesResult {
let writing_mode = constraint_space.writing_mode; let writing_mode = constraint_space.writing_mode;
let layout_style = self.layout_style();
let mut layout = TableLayout::new(self); let mut layout = TableLayout::new(self);
layout.pbm = self layout.pbm = layout_style
.style
.padding_border_margin_with_writing_mode_and_containing_block_inline_size( .padding_border_margin_with_writing_mode_and_containing_block_inline_size(
writing_mode, writing_mode,
Au::zero(), Au::zero(),
@ -2769,11 +2783,10 @@ impl ComputeInlineContentSizes for Table {
// Padding and border should apply to the table grid, but they will be taken into // Padding and border should apply to the table grid, but they will be taken into
// account when computing the inline content sizes of the table wrapper (our parent), so // account when computing the inline content sizes of the table wrapper (our parent), so
// this code removes their contribution from the inline content size of the caption. // this code removes their contribution from the inline content size of the caption.
let padding = self let padding = layout_style
.style
.padding(writing_mode) .padding(writing_mode)
.percentages_relative_to(Au::zero()); .percentages_relative_to(Au::zero());
let border = self.style.border_width(writing_mode); let border = layout_style.border_width(writing_mode);
caption_minimum_inline_size -= padding.inline_sum() + border.inline_sum(); caption_minimum_inline_size -= padding.inline_sum() + border.inline_sum();
table_content_sizes table_content_sizes
.min_content .min_content
@ -2790,7 +2803,38 @@ impl ComputeInlineContentSizes for Table {
} }
} }
impl Table {
#[inline]
pub(crate) fn layout_style(&self) -> LayoutStyle {
LayoutStyle::Table(&self.style)
}
#[inline]
pub(crate) fn layout_style_for_grid(&self) -> LayoutStyle {
LayoutStyle::Default(&self.grid_style)
}
}
impl TableTrack {
#[inline]
pub(crate) fn layout_style(&self) -> LayoutStyle {
LayoutStyle::Default(&self.style)
}
}
impl TableTrackGroup {
#[inline]
pub(crate) fn layout_style(&self) -> LayoutStyle {
LayoutStyle::Default(&self.style)
}
}
impl TableSlotCell { impl TableSlotCell {
#[inline]
fn layout_style(&self) -> LayoutStyle {
self.contents.layout_style(&self.base)
}
fn effective_vertical_align(&self) -> VerticalAlignKeyword { fn effective_vertical_align(&self) -> VerticalAlignKeyword {
match self.base.style.clone_vertical_align() { match self.base.style.clone_vertical_align() {
VerticalAlign::Keyword(VerticalAlignKeyword::Top) => VerticalAlignKeyword::Top, VerticalAlign::Keyword(VerticalAlignKeyword::Top) => VerticalAlignKeyword::Top,

View file

@ -27,7 +27,7 @@ use crate::geom::{
}; };
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext, PositioningContextLength}; use crate::positioned::{AbsolutelyPositionedBox, PositioningContext, PositioningContextLength};
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult}; use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
use crate::style_ext::ComputedValuesExt; use crate::style_ext::LayoutStyle;
use crate::{ConstraintSpace, ContainingBlock, ContainingBlockSize}; use crate::{ConstraintSpace, ContainingBlock, ContainingBlockSize};
const DUMMY_NODE_ID: taffy::NodeId = taffy::NodeId::new(u64::MAX); const DUMMY_NODE_ID: taffy::NodeId = taffy::NodeId::new(u64::MAX);
@ -136,7 +136,9 @@ impl taffy::LayoutPartialTree for TaffyContainerContext<'_> {
let style = independent_context.style(); let style = independent_context.style();
// Adjust known_dimensions from border box to content box // Adjust known_dimensions from border box to content box
let pbm = style.padding_border_margin(containing_block); let pbm = independent_context
.layout_style()
.padding_border_margin(containing_block);
let pb_sum = pbm.padding_border_sums.map(|v| v.to_f32_px()); let pb_sum = pbm.padding_border_sums.map(|v| v.to_f32_px());
let margin_sum = pbm.margin.auto_is(Au::zero).sum().map(|v| v.to_f32_px()); let margin_sum = pbm.margin.auto_is(Au::zero).sum().map(|v| v.to_f32_px());
let content_box_inset = pb_sum + margin_sum; let content_box_inset = pb_sum + margin_sum;
@ -387,7 +389,8 @@ impl ComputeInlineContentSizes for TaffyContainer {
_ => panic!("Servo is only configured to use Taffy for CSS Grid layout"), _ => panic!("Servo is only configured to use Taffy for CSS Grid layout"),
}; };
let pb_sums = style let pb_sums = self
.layout_style()
.padding_border_margin(containing_block) .padding_border_margin(containing_block)
.padding_border_sums; .padding_border_sums;
@ -428,7 +431,7 @@ impl TaffyContainer {
let container_style = &content_box_size_override.style; let container_style = &content_box_size_override.style;
let align_items = container_style.clone_align_items(); let align_items = container_style.clone_align_items();
let justify_items = container_style.clone_justify_items(); let justify_items = container_style.clone_justify_items();
let pbm = container_style.padding_border_margin(containing_block); let pbm = self.layout_style().padding_border_margin(containing_block);
let known_dimensions = taffy::Size { let known_dimensions = taffy::Size {
width: Some( width: Some(
@ -625,4 +628,9 @@ impl TaffyContainer {
detailed_layout_info: container_ctx.detailed_layout_info, detailed_layout_info: container_ctx.detailed_layout_info,
} }
} }
#[inline]
pub(crate) fn layout_style(&self) -> LayoutStyle {
LayoutStyle::Default(&self.style)
}
} }