mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
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:
parent
7e7792dfbd
commit
60dc3b26fb
11 changed files with 368 additions and 238 deletions
|
@ -38,7 +38,7 @@ use crate::layout_box_base::LayoutBoxBase;
|
|||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext, PositioningContextLength};
|
||||
use crate::replaced::ReplacedContents;
|
||||
use crate::sizing::{self, ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
|
||||
use crate::style_ext::{ComputedValuesExt, ContentBoxSizesAndPBM, PaddingBorderMargin};
|
||||
use crate::style_ext::{ContentBoxSizesAndPBM, LayoutStyle, PaddingBorderMargin};
|
||||
use crate::{
|
||||
ConstraintSpace, ContainingBlock, ContainingBlockSize, IndefiniteContainingBlock,
|
||||
SizeConstraint,
|
||||
|
@ -105,19 +105,22 @@ impl BlockLevelBox {
|
|||
collected_margin: &mut CollapsedMargin,
|
||||
containing_block: &ContainingBlock,
|
||||
) -> bool {
|
||||
let style = match self {
|
||||
BlockLevelBox::SameFormattingContextBlock { base, .. } => &base.style,
|
||||
let layout_style = match self {
|
||||
BlockLevelBox::SameFormattingContextBlock { base, contents, .. } => {
|
||||
contents.layout_style(base)
|
||||
},
|
||||
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(_) |
|
||||
BlockLevelBox::OutOfFlowFloatBox(_) => return true,
|
||||
BlockLevelBox::OutsideMarker(_) => return false,
|
||||
BlockLevelBox::Independent(ref context) => {
|
||||
// FIXME: If the element doesn't fit next to floats, it will get clearance.
|
||||
// In that case this should be returning false.
|
||||
context.style()
|
||||
context.layout_style()
|
||||
},
|
||||
};
|
||||
|
||||
// FIXME: This should only return false when 'clear' causes clearance.
|
||||
let style = layout_style.style();
|
||||
if style.get_box().clear != StyleClear::None {
|
||||
return false;
|
||||
}
|
||||
|
@ -126,7 +129,7 @@ impl BlockLevelBox {
|
|||
content_box_sizes,
|
||||
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);
|
||||
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
|
||||
// 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.
|
||||
let pbm_of_list_item = self
|
||||
.list_item_style()
|
||||
.padding_border_margin(containing_block);
|
||||
//
|
||||
// TODO: This should use the LayoutStyle of the list item, not the default one. Currently
|
||||
// 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 {
|
||||
start_corner: LogicalVec2 {
|
||||
inline: -max_inline_size -
|
||||
|
@ -387,6 +392,11 @@ impl BlockFormattingContext {
|
|||
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.
|
||||
|
@ -425,7 +435,7 @@ fn compute_inline_content_sizes_for_block_level_boxes(
|
|||
},
|
||||
BlockLevelBox::SameFormattingContextBlock { base, contents, .. } => {
|
||||
let inline_content_sizes_result = sizing::outer_inline(
|
||||
&base.style,
|
||||
&contents.layout_style(base),
|
||||
containing_block,
|
||||
&LogicalVec2::zero(),
|
||||
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 {
|
||||
|
@ -824,6 +839,7 @@ fn layout_in_flow_non_replaced_block_level_same_formatting_context(
|
|||
collapsible_with_parent_start_margin: Option<CollapsibleWithParentStartMargin>,
|
||||
) -> BoxFragment {
|
||||
let style = &base.style;
|
||||
let layout_style = contents.layout_style(base);
|
||||
let containing_block_writing_mode = containing_block.style.writing_mode;
|
||||
let get_inline_content_sizes = |constraint_space: &ConstraintSpace| {
|
||||
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,
|
||||
} = solve_containing_block_padding_and_border_for_in_flow_box(
|
||||
containing_block,
|
||||
style,
|
||||
&layout_style,
|
||||
get_inline_content_sizes,
|
||||
false, /* is_table */
|
||||
);
|
||||
|
@ -1071,6 +1087,7 @@ impl IndependentNonReplacedContents {
|
|||
base.inline_content_sizes(layout_context, constraint_space, self)
|
||||
.sizes
|
||||
};
|
||||
let layout_style = self.layout_style(base);
|
||||
let ContainingBlockPaddingAndBorder {
|
||||
containing_block: containing_block_for_children,
|
||||
pbm,
|
||||
|
@ -1079,7 +1096,7 @@ impl IndependentNonReplacedContents {
|
|||
available_block_size,
|
||||
} = solve_containing_block_padding_and_border_for_in_flow_box(
|
||||
containing_block,
|
||||
&base.style,
|
||||
&layout_style,
|
||||
get_inline_content_sizes,
|
||||
self.is_table(),
|
||||
);
|
||||
|
@ -1163,7 +1180,9 @@ impl IndependentNonReplacedContents {
|
|||
content_box_sizes,
|
||||
pbm,
|
||||
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) =
|
||||
solve_block_margins_for_in_flow_block_level(&pbm);
|
||||
|
@ -1468,8 +1487,8 @@ impl ReplacedContents {
|
|||
containing_block: &ContainingBlock,
|
||||
mut sequential_layout_state: Option<&mut SequentialLayoutState>,
|
||||
) -> BoxFragment {
|
||||
let content_box_sizes_and_pbm = base
|
||||
.style
|
||||
let content_box_sizes_and_pbm = self
|
||||
.layout_style(base)
|
||||
.content_box_sizes_and_padding_border_margin(&containing_block.into());
|
||||
let pbm = &content_box_sizes_and_pbm.pbm;
|
||||
let content_size = self.used_size_as_if_inline_element(
|
||||
|
@ -1618,10 +1637,11 @@ struct ResolvedMargins {
|
|||
/// inline size could then be incorrect.
|
||||
fn solve_containing_block_padding_and_border_for_in_flow_box<'a>(
|
||||
containing_block: &ContainingBlock<'_>,
|
||||
style: &'a Arc<ComputedValues>,
|
||||
layout_style: &'a LayoutStyle,
|
||||
get_inline_content_sizes: impl FnOnce(&ConstraintSpace) -> ContentSizes,
|
||||
is_table: bool,
|
||||
) -> ContainingBlockPaddingAndBorder<'a> {
|
||||
let style = layout_style.style();
|
||||
if matches!(style.pseudo(), Some(PseudoElement::ServoAnonymousBox)) {
|
||||
// <https://drafts.csswg.org/css2/#anonymous-block-level>
|
||||
// > 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,
|
||||
pbm,
|
||||
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 pbm_sums = pbm.padding + pbm.border + margin;
|
||||
|
@ -2140,8 +2160,9 @@ impl IndependentFormattingContext {
|
|||
) -> IndependentLayoutResult {
|
||||
let style = self.style();
|
||||
let container_writing_mode = containing_block.style.writing_mode;
|
||||
let content_box_sizes_and_pbm =
|
||||
style.content_box_sizes_and_padding_border_margin(&containing_block.into());
|
||||
let content_box_sizes_and_pbm = self
|
||||
.layout_style()
|
||||
.content_box_sizes_and_padding_border_margin(&containing_block.into());
|
||||
let pbm = &content_box_sizes_and_pbm.pbm;
|
||||
let margin = pbm.margin.auto_is(Au::zero);
|
||||
let pbm_sums = pbm.padding + pbm.border + margin;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue