mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
layout: Take percentage columns into account when sizing table grid min and max (#35167)
The specification doesn't say how to deal with percentages when determining the minimum and maximum size of a table grid, so follow the approach that Chromium uses. Essentially, figure out the "missing" percentage from the non-percentage columns and then use that to work backwards to fine the size of the percentage ones. This change is larger than one might expect, because this percentage approach shouldn't happen for tables that are descendants of a flex, grid or table container (except when there is an interceding absolute). We have to pass this information down when building the box tree. This will also make it easier to improve propagated text decorations in the future. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
d5fcc5a5d5
commit
6b04bc6263
26 changed files with 228 additions and 226 deletions
|
@ -7,7 +7,6 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||
use style::values::computed::TextDecorationLine;
|
||||
|
||||
use crate::context::LayoutContext;
|
||||
use crate::dom::{BoxSlot, NodeExt};
|
||||
|
@ -20,12 +19,13 @@ use crate::formatting_contexts::{
|
|||
};
|
||||
use crate::layout_box_base::LayoutBoxBase;
|
||||
use crate::style_ext::DisplayGeneratingBox;
|
||||
use crate::PropagatedBoxTreeData;
|
||||
|
||||
/// <https://drafts.csswg.org/css-flexbox/#flex-items>
|
||||
/// A builder used for both flex and grid containers.
|
||||
pub(crate) struct ModernContainerBuilder<'a, 'dom, Node> {
|
||||
context: &'a LayoutContext<'a>,
|
||||
info: &'a NodeAndStyleInfo<Node>,
|
||||
text_decoration_line: TextDecorationLine,
|
||||
propagated_data: PropagatedBoxTreeData,
|
||||
contiguous_text_runs: Vec<ModernContainerTextRun<'dom, Node>>,
|
||||
/// To be run in parallel with rayon in `finish`
|
||||
jobs: Vec<ModernContainerJob<'dom, Node>>,
|
||||
|
@ -108,12 +108,12 @@ where
|
|||
pub fn new(
|
||||
context: &'a LayoutContext<'a>,
|
||||
info: &'a NodeAndStyleInfo<Node>,
|
||||
text_decoration_line: TextDecorationLine,
|
||||
propagated_data: PropagatedBoxTreeData,
|
||||
) -> Self {
|
||||
ModernContainerBuilder {
|
||||
context,
|
||||
info,
|
||||
text_decoration_line,
|
||||
propagated_data: propagated_data.disallowing_percentage_table_columns(),
|
||||
contiguous_text_runs: Vec::new(),
|
||||
jobs: Vec::new(),
|
||||
has_text_runs: false,
|
||||
|
@ -164,7 +164,7 @@ where
|
|||
|
||||
let inline_formatting_context = inline_formatting_context_builder.finish(
|
||||
self.context,
|
||||
self.text_decoration_line,
|
||||
self.propagated_data,
|
||||
true, /* has_first_formatted_line */
|
||||
false, /* is_single_line_text_box */
|
||||
self.info.style.writing_mode.to_bidi_level(),
|
||||
|
@ -195,17 +195,21 @@ where
|
|||
box_slot,
|
||||
} => {
|
||||
let is_abspos = info.style.get_box().position.is_absolutely_positioned();
|
||||
|
||||
// Text decorations are not propagated to any out-of-flow descendants. In addition,
|
||||
// absolutes don't affect the size of ancestors so it is fine to allow descendent
|
||||
// tables to resolve percentage columns.
|
||||
let propagated_data = match is_abspos {
|
||||
false => self.propagated_data,
|
||||
true => PropagatedBoxTreeData::default(),
|
||||
};
|
||||
|
||||
let formatting_context = IndependentFormattingContext::construct(
|
||||
self.context,
|
||||
&info,
|
||||
display.display_inside(),
|
||||
contents,
|
||||
// Text decorations are not propagated to any out-of-flow descendants.
|
||||
if is_abspos {
|
||||
TextDecorationLine::NONE
|
||||
} else {
|
||||
self.text_decoration_line
|
||||
},
|
||||
propagated_data,
|
||||
);
|
||||
|
||||
if is_abspos {
|
||||
|
|
|
@ -12,7 +12,6 @@ use style::properties::longhands::flex_wrap::computed_value::T as FlexWrap;
|
|||
use style::properties::ComputedValues;
|
||||
use style::values::computed::{AlignContent, JustifyContent};
|
||||
use style::values::specified::align::AlignFlags;
|
||||
use style::values::specified::text::TextDecorationLine;
|
||||
|
||||
use crate::cell::ArcRefCell;
|
||||
use crate::construct_modern::{ModernContainerBuilder, ModernItemKind};
|
||||
|
@ -22,7 +21,7 @@ use crate::dom_traversal::{NodeAndStyleInfo, NonReplacedContents};
|
|||
use crate::formatting_contexts::{IndependentFormattingContext, IndependentLayout};
|
||||
use crate::fragment_tree::BaseFragmentInfo;
|
||||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
||||
use crate::ContainingBlock;
|
||||
use crate::{ContainingBlock, PropagatedBoxTreeData};
|
||||
|
||||
mod geom;
|
||||
mod layout;
|
||||
|
@ -102,12 +101,10 @@ impl FlexContainer {
|
|||
context: &LayoutContext,
|
||||
info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
|
||||
contents: NonReplacedContents,
|
||||
propagated_text_decoration_line: TextDecorationLine,
|
||||
propagated_data: PropagatedBoxTreeData,
|
||||
) -> Self {
|
||||
let text_decoration_line =
|
||||
propagated_text_decoration_line | info.style.clone_text_decoration_line();
|
||||
|
||||
let mut builder = ModernContainerBuilder::new(context, info, text_decoration_line);
|
||||
let mut builder =
|
||||
ModernContainerBuilder::new(context, info, propagated_data.union(&info.style));
|
||||
contents.traverse(context, info, &mut builder);
|
||||
let items = builder.finish();
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ use style::properties::longhands::list_style_position::computed_value::T as List
|
|||
use style::properties::ComputedValues;
|
||||
use style::selector_parser::PseudoElement;
|
||||
use style::str::char_is_whitespace;
|
||||
use style::values::specified::text::TextDecorationLine;
|
||||
|
||||
use super::inline::construct::InlineFormattingContextBuilder;
|
||||
use super::inline::inline_box::InlineBox;
|
||||
|
@ -30,13 +29,14 @@ use crate::layout_box_base::LayoutBoxBase;
|
|||
use crate::positioned::AbsolutelyPositionedBox;
|
||||
use crate::style_ext::{ComputedValuesExt, DisplayGeneratingBox, DisplayInside, DisplayOutside};
|
||||
use crate::table::{AnonymousTableContent, Table};
|
||||
use crate::PropagatedBoxTreeData;
|
||||
|
||||
impl BlockFormattingContext {
|
||||
pub(crate) fn construct<'dom, Node>(
|
||||
context: &LayoutContext,
|
||||
info: &NodeAndStyleInfo<Node>,
|
||||
contents: NonReplacedContents,
|
||||
propagated_text_decoration_line: TextDecorationLine,
|
||||
propagated_data: PropagatedBoxTreeData,
|
||||
is_list_item: bool,
|
||||
) -> Self
|
||||
where
|
||||
|
@ -46,7 +46,7 @@ impl BlockFormattingContext {
|
|||
context,
|
||||
info,
|
||||
contents,
|
||||
propagated_text_decoration_line,
|
||||
propagated_data,
|
||||
is_list_item,
|
||||
))
|
||||
}
|
||||
|
@ -63,6 +63,7 @@ impl BlockFormattingContext {
|
|||
struct BlockLevelJob<'dom, Node> {
|
||||
info: NodeAndStyleInfo<Node>,
|
||||
box_slot: BoxSlot<'dom>,
|
||||
propagated_data: PropagatedBoxTreeData,
|
||||
kind: BlockLevelCreator,
|
||||
}
|
||||
|
||||
|
@ -71,7 +72,6 @@ enum BlockLevelCreator {
|
|||
Independent {
|
||||
display_inside: DisplayInside,
|
||||
contents: Contents,
|
||||
propagated_text_decoration_line: TextDecorationLine,
|
||||
},
|
||||
OutOfFlowAbsolutelyPositionedBox {
|
||||
display_inside: DisplayInside,
|
||||
|
@ -100,7 +100,7 @@ enum IntermediateBlockContainer {
|
|||
InlineFormattingContext(BlockContainer),
|
||||
Deferred {
|
||||
contents: NonReplacedContents,
|
||||
propagated_text_decoration_line: TextDecorationLine,
|
||||
propagated_data: PropagatedBoxTreeData,
|
||||
is_list_item: bool,
|
||||
},
|
||||
}
|
||||
|
@ -135,8 +135,8 @@ pub(crate) struct BlockContainerBuilder<'dom, 'style, Node> {
|
|||
/// be considered the first line for the purposes of `text-indent`.
|
||||
have_already_seen_first_line_for_text_indent: bool,
|
||||
|
||||
/// The propagated [`TextDecorationLine`].
|
||||
text_decoration_line: TextDecorationLine,
|
||||
/// The propagated data to use for BoxTree construction.
|
||||
propagated_data: PropagatedBoxTreeData,
|
||||
|
||||
inline_formatting_context_builder: InlineFormattingContextBuilder,
|
||||
|
||||
|
@ -155,14 +155,13 @@ impl BlockContainer {
|
|||
context: &LayoutContext,
|
||||
info: &NodeAndStyleInfo<Node>,
|
||||
contents: NonReplacedContents,
|
||||
propagated_text_decoration_line: TextDecorationLine,
|
||||
propagated_data: PropagatedBoxTreeData,
|
||||
is_list_item: bool,
|
||||
) -> BlockContainer
|
||||
where
|
||||
Node: NodeExt<'dom>,
|
||||
{
|
||||
let mut builder =
|
||||
BlockContainerBuilder::new(context, info, propagated_text_decoration_line);
|
||||
let mut builder = BlockContainerBuilder::new(context, info, propagated_data);
|
||||
|
||||
if is_list_item {
|
||||
if let Some(marker_contents) = crate::lists::make_marker(context, info) {
|
||||
|
@ -189,16 +188,13 @@ where
|
|||
pub(crate) fn new(
|
||||
context: &'style LayoutContext,
|
||||
info: &'style NodeAndStyleInfo<Node>,
|
||||
propagated_text_decoration_line: TextDecorationLine,
|
||||
propagated_data: PropagatedBoxTreeData,
|
||||
) -> Self {
|
||||
let text_decoration_line =
|
||||
propagated_text_decoration_line | info.style.clone_text_decoration_line();
|
||||
|
||||
BlockContainerBuilder {
|
||||
context,
|
||||
info,
|
||||
block_level_boxes: Vec::new(),
|
||||
text_decoration_line,
|
||||
propagated_data: propagated_data.union(&info.style),
|
||||
have_already_seen_first_line_for_text_indent: false,
|
||||
anonymous_style: None,
|
||||
anonymous_table_content: Vec::new(),
|
||||
|
@ -215,7 +211,7 @@ where
|
|||
|
||||
if let Some(inline_formatting_context) = self.inline_formatting_context_builder.finish(
|
||||
self.context,
|
||||
self.text_decoration_line,
|
||||
self.propagated_data,
|
||||
!self.have_already_seen_first_line_for_text_indent,
|
||||
self.info.is_single_line_text_input(),
|
||||
self.info.style.writing_mode.to_bidi_level(),
|
||||
|
@ -266,10 +262,9 @@ where
|
|||
// > Note that text decorations are not propagated to floating and absolutely
|
||||
// > positioned descendants, nor to the contents of atomic inline-level descendants
|
||||
// > such as inline blocks and inline tables.
|
||||
let propagated_text_decoration_line = if inline_table {
|
||||
TextDecorationLine::NONE
|
||||
} else {
|
||||
self.text_decoration_line
|
||||
let propagated_data = match inline_table {
|
||||
true => self.propagated_data.without_text_decorations(),
|
||||
false => self.propagated_data,
|
||||
};
|
||||
|
||||
let contents: Vec<AnonymousTableContent<'dom, Node>> =
|
||||
|
@ -279,12 +274,7 @@ where
|
|||
_ => None,
|
||||
};
|
||||
|
||||
let ifc = Table::construct_anonymous(
|
||||
self.context,
|
||||
self.info,
|
||||
contents,
|
||||
propagated_text_decoration_line,
|
||||
);
|
||||
let ifc = Table::construct_anonymous(self.context, self.info, contents, propagated_data);
|
||||
|
||||
if inline_table {
|
||||
self.inline_formatting_context_builder.push_atomic(ifc);
|
||||
|
@ -296,6 +286,7 @@ where
|
|||
info: anonymous_info,
|
||||
box_slot: BoxSlot::dummy(),
|
||||
kind: BlockLevelCreator::AnonymousTable { table_block },
|
||||
propagated_data,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -418,6 +409,7 @@ where
|
|||
info: info.clone(),
|
||||
box_slot: BoxSlot::dummy(),
|
||||
kind: BlockLevelCreator::OutsideMarker { contents },
|
||||
propagated_data: self.propagated_data.without_text_decorations(),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -439,7 +431,7 @@ where
|
|||
display_inside,
|
||||
contents,
|
||||
// Text decorations are not propagated to atomic inline-level descendants.
|
||||
TextDecorationLine::NONE,
|
||||
self.propagated_data.without_text_decorations(),
|
||||
),
|
||||
);
|
||||
box_slot.set(LayoutBox::InlineLevel(atomic));
|
||||
|
@ -489,7 +481,7 @@ where
|
|||
.inline_formatting_context_builder
|
||||
.split_around_block_and_finish(
|
||||
self.context,
|
||||
self.text_decoration_line,
|
||||
self.propagated_data,
|
||||
!self.have_already_seen_first_line_for_text_indent,
|
||||
self.info.style.writing_mode.to_bidi_level(),
|
||||
)
|
||||
|
@ -497,7 +489,7 @@ where
|
|||
self.push_block_level_job_for_inline_formatting_context(inline_formatting_context);
|
||||
}
|
||||
|
||||
let propagated_text_decoration_line = self.text_decoration_line;
|
||||
let propagated_data = self.propagated_data;
|
||||
let kind = match contents {
|
||||
Contents::NonReplaced(contents) => match display_inside {
|
||||
DisplayInside::Flow { is_list_item }
|
||||
|
@ -506,7 +498,7 @@ where
|
|||
BlockLevelCreator::SameFormattingContextBlock(
|
||||
IntermediateBlockContainer::Deferred {
|
||||
contents,
|
||||
propagated_text_decoration_line,
|
||||
propagated_data,
|
||||
is_list_item,
|
||||
},
|
||||
)
|
||||
|
@ -514,7 +506,6 @@ where
|
|||
_ => BlockLevelCreator::Independent {
|
||||
display_inside,
|
||||
contents: contents.into(),
|
||||
propagated_text_decoration_line,
|
||||
},
|
||||
},
|
||||
Contents::Replaced(contents) => {
|
||||
|
@ -522,7 +513,6 @@ where
|
|||
BlockLevelCreator::Independent {
|
||||
display_inside,
|
||||
contents,
|
||||
propagated_text_decoration_line,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -530,6 +520,7 @@ where
|
|||
info: info.clone(),
|
||||
box_slot,
|
||||
kind,
|
||||
propagated_data,
|
||||
});
|
||||
|
||||
// Any block also counts as the first line for the purposes of text indent. Even if
|
||||
|
@ -565,6 +556,7 @@ where
|
|||
info: info.clone(),
|
||||
box_slot,
|
||||
kind,
|
||||
propagated_data: self.propagated_data.without_text_decorations(),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -583,6 +575,7 @@ where
|
|||
info,
|
||||
display_inside,
|
||||
contents,
|
||||
self.propagated_data,
|
||||
));
|
||||
box_slot.set(LayoutBox::InlineLevel(inline_level_box));
|
||||
return;
|
||||
|
@ -596,13 +589,14 @@ where
|
|||
info: info.clone(),
|
||||
box_slot,
|
||||
kind,
|
||||
propagated_data: self.propagated_data.without_text_decorations(),
|
||||
});
|
||||
}
|
||||
|
||||
fn end_ongoing_inline_formatting_context(&mut self) {
|
||||
if let Some(inline_formatting_context) = self.inline_formatting_context_builder.finish(
|
||||
self.context,
|
||||
self.text_decoration_line,
|
||||
self.propagated_data,
|
||||
!self.have_already_seen_first_line_for_text_indent,
|
||||
self.info.is_single_line_text_input(),
|
||||
self.info.style.writing_mode.to_bidi_level(),
|
||||
|
@ -638,6 +632,7 @@ where
|
|||
BlockContainer::InlineFormattingContext(inline_formatting_context),
|
||||
),
|
||||
),
|
||||
propagated_data: self.propagated_data,
|
||||
});
|
||||
|
||||
self.have_already_seen_first_line_for_text_indent = true;
|
||||
|
@ -663,14 +658,13 @@ where
|
|||
BlockLevelCreator::Independent {
|
||||
display_inside,
|
||||
contents,
|
||||
propagated_text_decoration_line,
|
||||
} => {
|
||||
let context = IndependentFormattingContext::construct(
|
||||
context,
|
||||
info,
|
||||
display_inside,
|
||||
contents,
|
||||
propagated_text_decoration_line,
|
||||
self.propagated_data,
|
||||
);
|
||||
ArcRefCell::new(BlockLevelBox::Independent(context))
|
||||
},
|
||||
|
@ -693,6 +687,7 @@ where
|
|||
info,
|
||||
display_inside,
|
||||
contents,
|
||||
self.propagated_data,
|
||||
))),
|
||||
BlockLevelCreator::OutsideMarker { contents } => {
|
||||
let marker_style = context
|
||||
|
@ -708,7 +703,7 @@ where
|
|||
context,
|
||||
&info.new_replacing_style(marker_style.clone()),
|
||||
contents,
|
||||
TextDecorationLine::empty(),
|
||||
self.propagated_data.without_text_decorations(),
|
||||
false, /* is_list_item */
|
||||
);
|
||||
ArcRefCell::new(BlockLevelBox::OutsideMarker(OutsideMarker {
|
||||
|
@ -737,15 +732,9 @@ impl IntermediateBlockContainer {
|
|||
match self {
|
||||
IntermediateBlockContainer::Deferred {
|
||||
contents,
|
||||
propagated_text_decoration_line,
|
||||
propagated_data,
|
||||
is_list_item,
|
||||
} => BlockContainer::construct(
|
||||
context,
|
||||
info,
|
||||
contents,
|
||||
propagated_text_decoration_line,
|
||||
is_list_item,
|
||||
),
|
||||
} => BlockContainer::construct(context, info, contents, propagated_data, is_list_item),
|
||||
IntermediateBlockContainer::InlineFormattingContext(block_container) => block_container,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ use style::computed_values::position::T as Position;
|
|||
use style::logical_geometry::WritingMode;
|
||||
use style::properties::ComputedValues;
|
||||
use style::values::computed::Clear as StyleClear;
|
||||
use style::values::specified::text::TextDecorationLine;
|
||||
|
||||
use crate::context::LayoutContext;
|
||||
use crate::dom::NodeExt;
|
||||
|
@ -29,7 +28,7 @@ use crate::fragment_tree::{BoxFragment, CollapsedMargin};
|
|||
use crate::geom::{LogicalRect, LogicalVec2, ToLogical};
|
||||
use crate::positioned::{relative_adjustement, PositioningContext};
|
||||
use crate::style_ext::{DisplayInside, PaddingBorderMargin};
|
||||
use crate::ContainingBlock;
|
||||
use crate::{ContainingBlock, PropagatedBoxTreeData};
|
||||
|
||||
/// A floating box.
|
||||
#[derive(Debug)]
|
||||
|
@ -902,6 +901,7 @@ impl FloatBox {
|
|||
info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
|
||||
display_inside: DisplayInside,
|
||||
contents: Contents,
|
||||
propagated_data: PropagatedBoxTreeData,
|
||||
) -> Self {
|
||||
Self {
|
||||
contents: IndependentFormattingContext::construct(
|
||||
|
@ -910,7 +910,7 @@ impl FloatBox {
|
|||
display_inside,
|
||||
contents,
|
||||
// Text decorations are not propagated to any out-of-flow descendants
|
||||
TextDecorationLine::NONE,
|
||||
propagated_data.without_text_decorations(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ use std::char::{ToLowercase, ToUppercase};
|
|||
use icu_segmenter::WordSegmenter;
|
||||
use servo_arc::Arc;
|
||||
use style::computed_values::white_space_collapse::T as WhiteSpaceCollapse;
|
||||
use style::values::computed::TextDecorationLine;
|
||||
use style::values::specified::text::TextTransformCase;
|
||||
use unicode_bidi::Level;
|
||||
|
||||
|
@ -22,6 +21,7 @@ use crate::flow::float::FloatBox;
|
|||
use crate::formatting_contexts::IndependentFormattingContext;
|
||||
use crate::positioned::AbsolutelyPositionedBox;
|
||||
use crate::style_ext::ComputedValuesExt;
|
||||
use crate::PropagatedBoxTreeData;
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct InlineFormattingContextBuilder {
|
||||
|
@ -271,7 +271,7 @@ impl InlineFormattingContextBuilder {
|
|||
pub(crate) fn split_around_block_and_finish(
|
||||
&mut self,
|
||||
layout_context: &LayoutContext,
|
||||
text_decoration_line: TextDecorationLine,
|
||||
propagated_data: PropagatedBoxTreeData,
|
||||
has_first_formatted_line: bool,
|
||||
default_bidi_level: Level,
|
||||
) -> Option<InlineFormattingContext> {
|
||||
|
@ -303,7 +303,7 @@ impl InlineFormattingContextBuilder {
|
|||
|
||||
inline_builder_from_before_split.finish(
|
||||
layout_context,
|
||||
text_decoration_line,
|
||||
propagated_data,
|
||||
has_first_formatted_line,
|
||||
/* is_single_line_text_input = */ false,
|
||||
default_bidi_level,
|
||||
|
@ -314,7 +314,7 @@ impl InlineFormattingContextBuilder {
|
|||
pub(crate) fn finish(
|
||||
&mut self,
|
||||
layout_context: &LayoutContext,
|
||||
text_decoration_line: TextDecorationLine,
|
||||
propagated_data: PropagatedBoxTreeData,
|
||||
has_first_formatted_line: bool,
|
||||
is_single_line_text_input: bool,
|
||||
default_bidi_level: Level,
|
||||
|
@ -329,7 +329,7 @@ impl InlineFormattingContextBuilder {
|
|||
Some(InlineFormattingContext::new_with_builder(
|
||||
old_builder,
|
||||
layout_context,
|
||||
text_decoration_line,
|
||||
propagated_data,
|
||||
has_first_formatted_line,
|
||||
is_single_line_text_input,
|
||||
default_bidi_level,
|
||||
|
|
|
@ -127,7 +127,7 @@ use crate::geom::{LogicalRect, LogicalVec2, ToLogical};
|
|||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
||||
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
|
||||
use crate::style_ext::{ComputedValuesExt, PaddingBorderMargin};
|
||||
use crate::{ConstraintSpace, ContainingBlock};
|
||||
use crate::{ConstraintSpace, ContainingBlock, PropagatedBoxTreeData};
|
||||
|
||||
// From gfxFontConstants.h in Firefox.
|
||||
static FONT_SUBSCRIPT_OFFSET_RATIO: f32 = 0.20;
|
||||
|
@ -1519,7 +1519,7 @@ impl InlineFormattingContext {
|
|||
pub(super) fn new_with_builder(
|
||||
builder: InlineFormattingContextBuilder,
|
||||
layout_context: &LayoutContext,
|
||||
text_decoration_line: TextDecorationLine,
|
||||
propagated_data: PropagatedBoxTreeData,
|
||||
has_first_formatted_line: bool,
|
||||
is_single_line_text_input: bool,
|
||||
starting_bidi_level: Level,
|
||||
|
@ -1570,7 +1570,7 @@ impl InlineFormattingContext {
|
|||
inline_items: builder.inline_items,
|
||||
inline_boxes: builder.inline_boxes,
|
||||
font_metrics,
|
||||
text_decoration_line,
|
||||
text_decoration_line: propagated_data.text_decoration,
|
||||
has_first_formatted_line,
|
||||
contains_floats: builder.contains_floats,
|
||||
is_single_line_text_input,
|
||||
|
|
|
@ -30,7 +30,7 @@ use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
|||
use crate::replaced::ReplacedContents;
|
||||
use crate::style_ext::{ComputedValuesExt, Display, DisplayGeneratingBox, DisplayInside};
|
||||
use crate::taffy::{TaffyItemBox, TaffyItemBoxInner};
|
||||
use crate::DefiniteContainingBlock;
|
||||
use crate::{DefiniteContainingBlock, PropagatedBoxTreeData};
|
||||
|
||||
pub struct BoxTree {
|
||||
/// Contains typically exactly one block-level box, which was generated by the root element.
|
||||
|
@ -289,6 +289,8 @@ fn construct_for_root_element<'dom>(
|
|||
|
||||
let contents = ReplacedContents::for_element(root_element, context)
|
||||
.map_or_else(|| NonReplacedContents::OfElement.into(), Contents::Replaced);
|
||||
|
||||
let propagated_data = PropagatedBoxTreeData::default().union(&info.style);
|
||||
let root_box = if box_style.position.is_absolutely_positioned() {
|
||||
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(ArcRefCell::new(
|
||||
AbsolutelyPositionedBox::construct(context, &info, display_inside, contents),
|
||||
|
@ -299,15 +301,15 @@ fn construct_for_root_element<'dom>(
|
|||
&info,
|
||||
display_inside,
|
||||
contents,
|
||||
propagated_data,
|
||||
))
|
||||
} else {
|
||||
let propagated_text_decoration_line = info.style.clone_text_decoration_line();
|
||||
BlockLevelBox::Independent(IndependentFormattingContext::construct(
|
||||
context,
|
||||
&info,
|
||||
display_inside,
|
||||
contents,
|
||||
propagated_text_decoration_line,
|
||||
propagated_data,
|
||||
))
|
||||
};
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ use app_units::Au;
|
|||
use servo_arc::Arc;
|
||||
use style::properties::ComputedValues;
|
||||
use style::selector_parser::PseudoElement;
|
||||
use style::values::specified::text::TextDecorationLine;
|
||||
|
||||
use crate::context::LayoutContext;
|
||||
use crate::dom::NodeExt;
|
||||
|
@ -24,7 +23,9 @@ use crate::sizing::{self, ComputeInlineContentSizes, InlineContentSizesResult};
|
|||
use crate::style_ext::{AspectRatio, DisplayInside, LayoutStyle};
|
||||
use crate::table::Table;
|
||||
use crate::taffy::TaffyContainer;
|
||||
use crate::{ConstraintSpace, ContainingBlock, IndefiniteContainingBlock, LogicalVec2};
|
||||
use crate::{
|
||||
ConstraintSpace, ContainingBlock, IndefiniteContainingBlock, LogicalVec2, PropagatedBoxTreeData,
|
||||
};
|
||||
|
||||
/// <https://drafts.csswg.org/css-display/#independent-formatting-context>
|
||||
#[derive(Debug)]
|
||||
|
@ -102,7 +103,7 @@ impl IndependentFormattingContext {
|
|||
node_and_style_info: &NodeAndStyleInfo<Node>,
|
||||
display_inside: DisplayInside,
|
||||
contents: Contents,
|
||||
propagated_text_decoration_line: TextDecorationLine,
|
||||
propagated_data: PropagatedBoxTreeData,
|
||||
) -> Self {
|
||||
let mut base_fragment_info: BaseFragmentInfo = node_and_style_info.into();
|
||||
|
||||
|
@ -115,7 +116,7 @@ impl IndependentFormattingContext {
|
|||
context,
|
||||
node_and_style_info,
|
||||
non_replaced_contents,
|
||||
propagated_text_decoration_line,
|
||||
propagated_data,
|
||||
is_list_item,
|
||||
))
|
||||
},
|
||||
|
@ -124,7 +125,7 @@ impl IndependentFormattingContext {
|
|||
context,
|
||||
node_and_style_info,
|
||||
non_replaced_contents,
|
||||
propagated_text_decoration_line,
|
||||
propagated_data,
|
||||
))
|
||||
},
|
||||
DisplayInside::Flex => {
|
||||
|
@ -132,7 +133,7 @@ impl IndependentFormattingContext {
|
|||
context,
|
||||
node_and_style_info,
|
||||
non_replaced_contents,
|
||||
propagated_text_decoration_line,
|
||||
propagated_data,
|
||||
))
|
||||
},
|
||||
DisplayInside::Table => {
|
||||
|
@ -150,7 +151,7 @@ impl IndependentFormattingContext {
|
|||
node_and_style_info,
|
||||
table_grid_style,
|
||||
non_replaced_contents,
|
||||
propagated_text_decoration_line,
|
||||
propagated_data,
|
||||
))
|
||||
},
|
||||
};
|
||||
|
|
|
@ -33,6 +33,7 @@ pub use fragment_tree::FragmentTree;
|
|||
use geom::AuOrAuto;
|
||||
use style::logical_geometry::WritingMode;
|
||||
use style::properties::ComputedValues;
|
||||
use style::values::computed::TextDecorationLine;
|
||||
|
||||
use crate::geom::{LogicalVec2, SizeConstraint};
|
||||
use crate::style_ext::AspectRatio;
|
||||
|
@ -140,3 +141,46 @@ impl<'a> From<&'_ DefiniteContainingBlock<'a>> for ContainingBlock<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data that is propagated from ancestors to descendants during [`crate::flow::BoxTree`]
|
||||
/// construction. This allows data to flow in the reverse direction of the typical layout
|
||||
/// propoagation, but only during `BoxTree` construction.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
struct PropagatedBoxTreeData {
|
||||
text_decoration: TextDecorationLine,
|
||||
allow_percentage_column_in_tables: bool,
|
||||
}
|
||||
|
||||
impl Default for PropagatedBoxTreeData {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
text_decoration: Default::default(),
|
||||
allow_percentage_column_in_tables: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PropagatedBoxTreeData {
|
||||
pub(crate) fn union(&self, style: &ComputedValues) -> Self {
|
||||
Self {
|
||||
// FIXME(#31736): This is only taking into account the line style and not the decoration
|
||||
// color. This should collect information about both so that they can be rendered properly.
|
||||
text_decoration: self.text_decoration | style.clone_text_decoration_line(),
|
||||
allow_percentage_column_in_tables: self.allow_percentage_column_in_tables,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn without_text_decorations(&self) -> Self {
|
||||
Self {
|
||||
text_decoration: TextDecorationLine::NONE,
|
||||
allow_percentage_column_in_tables: self.allow_percentage_column_in_tables,
|
||||
}
|
||||
}
|
||||
|
||||
fn disallowing_percentage_table_columns(&self) -> PropagatedBoxTreeData {
|
||||
Self {
|
||||
text_decoration: self.text_decoration,
|
||||
allow_percentage_column_in_tables: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ use style::computed_values::position::T as Position;
|
|||
use style::logical_geometry::WritingMode;
|
||||
use style::properties::ComputedValues;
|
||||
use style::values::specified::align::{AlignFlags, AxisDirection};
|
||||
use style::values::specified::text::TextDecorationLine;
|
||||
use style::Zero;
|
||||
|
||||
use crate::cell::ArcRefCell;
|
||||
|
@ -32,7 +31,8 @@ use crate::geom::{
|
|||
use crate::sizing::ContentSizes;
|
||||
use crate::style_ext::{ComputedValuesExt, ContentBoxSizesAndPBM, DisplayInside};
|
||||
use crate::{
|
||||
ConstraintSpace, ContainingBlock, ContainingBlockSize, DefiniteContainingBlock, SizeConstraint,
|
||||
ConstraintSpace, ContainingBlock, ContainingBlockSize, DefiniteContainingBlock,
|
||||
PropagatedBoxTreeData, SizeConstraint,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -75,8 +75,10 @@ impl AbsolutelyPositionedBox {
|
|||
node_info,
|
||||
display_inside,
|
||||
contents,
|
||||
// Text decorations are not propagated to any out-of-flow descendants.
|
||||
TextDecorationLine::NONE,
|
||||
// Text decorations are not propagated to any out-of-flow descendants. In addition,
|
||||
// absolutes don't affect the size of ancestors so it is fine to allow descendent
|
||||
// tables to resolve percentage columns.
|
||||
PropagatedBoxTreeData::default(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ use style::properties::style_structs::Font;
|
|||
use style::properties::ComputedValues;
|
||||
use style::selector_parser::PseudoElement;
|
||||
use style::str::char_is_whitespace;
|
||||
use style::values::specified::TextDecorationLine;
|
||||
|
||||
use super::{
|
||||
Table, TableCaption, TableSlot, TableSlotCell, TableSlotCoordinates, TableSlotOffset,
|
||||
|
@ -31,6 +30,7 @@ use crate::formatting_contexts::{
|
|||
use crate::fragment_tree::BaseFragmentInfo;
|
||||
use crate::layout_box_base::LayoutBoxBase;
|
||||
use crate::style_ext::{DisplayGeneratingBox, DisplayLayoutInternal};
|
||||
use crate::PropagatedBoxTreeData;
|
||||
|
||||
/// A reference to a slot and its coordinates in the table
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
|
@ -78,12 +78,14 @@ impl Table {
|
|||
info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
|
||||
grid_style: Arc<ComputedValues>,
|
||||
contents: NonReplacedContents,
|
||||
propagated_text_decoration_line: TextDecorationLine,
|
||||
propagated_data: PropagatedBoxTreeData,
|
||||
) -> Self {
|
||||
let text_decoration_line =
|
||||
propagated_text_decoration_line | info.style.clone_text_decoration_line();
|
||||
let mut traversal =
|
||||
TableBuilderTraversal::new(context, info, grid_style, text_decoration_line);
|
||||
let mut traversal = TableBuilderTraversal::new(
|
||||
context,
|
||||
info,
|
||||
grid_style,
|
||||
propagated_data.union(&info.style),
|
||||
);
|
||||
contents.traverse(context, info, &mut traversal);
|
||||
traversal.finish()
|
||||
}
|
||||
|
@ -92,7 +94,7 @@ impl Table {
|
|||
context: &LayoutContext,
|
||||
parent_info: &NodeAndStyleInfo<Node>,
|
||||
contents: Vec<AnonymousTableContent<'dom, Node>>,
|
||||
propagated_text_decoration_line: style::values::specified::TextDecorationLine,
|
||||
propagated_data: PropagatedBoxTreeData,
|
||||
) -> IndependentFormattingContext
|
||||
where
|
||||
Node: crate::dom::NodeExt<'dom>,
|
||||
|
@ -111,7 +113,7 @@ impl Table {
|
|||
context,
|
||||
&anonymous_info,
|
||||
grid_and_wrapper_style.clone(),
|
||||
propagated_text_decoration_line,
|
||||
propagated_data,
|
||||
);
|
||||
|
||||
for content in contents {
|
||||
|
@ -242,9 +244,15 @@ impl TableBuilder {
|
|||
style: Arc<ComputedValues>,
|
||||
grid_style: Arc<ComputedValues>,
|
||||
base_fragment_info: BaseFragmentInfo,
|
||||
percentage_columns_allowed_for_inline_content_sizes: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
table: Table::new(style, grid_style, base_fragment_info),
|
||||
table: Table::new(
|
||||
style,
|
||||
grid_style,
|
||||
base_fragment_info,
|
||||
percentage_columns_allowed_for_inline_content_sizes,
|
||||
),
|
||||
incoming_rowspans: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
@ -256,6 +264,7 @@ impl TableBuilder {
|
|||
testing_style.clone(),
|
||||
testing_style.clone(),
|
||||
BaseFragmentInfo::anonymous(),
|
||||
true, /* percentage_columns_allowed_for_inline_content_sizes */
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -627,9 +636,9 @@ pub(crate) struct TableBuilderTraversal<'style, 'dom, Node> {
|
|||
context: &'style LayoutContext<'style>,
|
||||
info: &'style NodeAndStyleInfo<Node>,
|
||||
|
||||
/// The value of the [`TextDecorationLine`] to use, either for the row group
|
||||
/// The value of the [`PropagatedBoxTreeData`] to use, either for the row group
|
||||
/// if processing one or for the table itself if outside a row group.
|
||||
current_text_decoration_line: TextDecorationLine,
|
||||
current_propagated_data: PropagatedBoxTreeData,
|
||||
|
||||
/// The [`TableBuilder`] for this [`TableBuilderTraversal`]. This is separated
|
||||
/// into another struct so that we can write unit tests against the builder.
|
||||
|
@ -649,13 +658,18 @@ where
|
|||
context: &'style LayoutContext<'style>,
|
||||
info: &'style NodeAndStyleInfo<Node>,
|
||||
grid_style: Arc<ComputedValues>,
|
||||
text_decoration_line: TextDecorationLine,
|
||||
propagated_data: PropagatedBoxTreeData,
|
||||
) -> Self {
|
||||
TableBuilderTraversal {
|
||||
context,
|
||||
info,
|
||||
current_text_decoration_line: text_decoration_line,
|
||||
builder: TableBuilder::new(info.style.clone(), grid_style, info.into()),
|
||||
current_propagated_data: propagated_data,
|
||||
builder: TableBuilder::new(
|
||||
info.style.clone(),
|
||||
grid_style,
|
||||
info.into(),
|
||||
propagated_data.allow_percentage_column_in_tables,
|
||||
),
|
||||
current_anonymous_row_content: Vec::new(),
|
||||
current_row_group_index: None,
|
||||
}
|
||||
|
@ -686,7 +700,7 @@ where
|
|||
);
|
||||
let anonymous_info = self.info.new_anonymous(anonymous_style.clone());
|
||||
let mut row_builder =
|
||||
TableRowBuilder::new(self, &anonymous_info, self.current_text_decoration_line);
|
||||
TableRowBuilder::new(self, &anonymous_info, self.current_propagated_data);
|
||||
|
||||
for cell_content in row_content {
|
||||
match cell_content {
|
||||
|
@ -758,8 +772,8 @@ where
|
|||
track_range: next_row_index..next_row_index,
|
||||
});
|
||||
|
||||
let previous_text_decoration_line = self.current_text_decoration_line;
|
||||
self.current_text_decoration_line |= info.style.clone_text_decoration_line();
|
||||
let previous_propagated_data = self.current_propagated_data;
|
||||
self.current_propagated_data = self.current_propagated_data.union(&info.style);
|
||||
|
||||
let new_row_group_index = self.builder.table.row_groups.len() - 1;
|
||||
self.current_row_group_index = Some(new_row_group_index);
|
||||
|
@ -772,7 +786,7 @@ where
|
|||
self.finish_anonymous_row_if_needed();
|
||||
|
||||
self.current_row_group_index = None;
|
||||
self.current_text_decoration_line = previous_text_decoration_line;
|
||||
self.current_propagated_data = previous_propagated_data;
|
||||
self.builder.incoming_rowspans.clear();
|
||||
|
||||
// We are doing this until we have actually set a Box for this `BoxSlot`.
|
||||
|
@ -784,7 +798,7 @@ where
|
|||
let context = self.context;
|
||||
|
||||
let mut row_builder =
|
||||
TableRowBuilder::new(self, info, self.current_text_decoration_line);
|
||||
TableRowBuilder::new(self, info, self.current_propagated_data);
|
||||
NonReplacedContents::try_from(contents).unwrap().traverse(
|
||||
context,
|
||||
info,
|
||||
|
@ -857,7 +871,7 @@ where
|
|||
self.context,
|
||||
info,
|
||||
non_replaced_contents,
|
||||
self.current_text_decoration_line,
|
||||
self.current_propagated_data,
|
||||
false, /* is_list_item */
|
||||
))
|
||||
},
|
||||
|
@ -910,8 +924,8 @@ struct TableRowBuilder<'style, 'builder, 'dom, 'a, Node> {
|
|||
|
||||
current_anonymous_cell_content: Vec<AnonymousTableContent<'dom, Node>>,
|
||||
|
||||
/// The [`TextDecorationLine`] to use for all children of this row.
|
||||
text_decoration_line: TextDecorationLine,
|
||||
/// The [`PropagatedBoxTreeData`] to use for all children of this row.
|
||||
propagated_data: PropagatedBoxTreeData,
|
||||
}
|
||||
|
||||
impl<'style, 'builder, 'dom, 'a, Node: 'dom> TableRowBuilder<'style, 'builder, 'dom, 'a, Node>
|
||||
|
@ -921,17 +935,15 @@ where
|
|||
fn new(
|
||||
table_traversal: &'builder mut TableBuilderTraversal<'style, 'dom, Node>,
|
||||
info: &'a NodeAndStyleInfo<Node>,
|
||||
propagated_text_decoration_line: TextDecorationLine,
|
||||
propagated_data: PropagatedBoxTreeData,
|
||||
) -> Self {
|
||||
table_traversal.builder.start_row();
|
||||
|
||||
let text_decoration_line =
|
||||
propagated_text_decoration_line | info.style.clone_text_decoration_line();
|
||||
TableRowBuilder {
|
||||
table_traversal,
|
||||
info,
|
||||
current_anonymous_cell_content: Vec::new(),
|
||||
text_decoration_line,
|
||||
propagated_data: propagated_data.union(&info.style),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -957,8 +969,9 @@ where
|
|||
&self.info.style,
|
||||
);
|
||||
let anonymous_info = self.info.new_anonymous(anonymous_style);
|
||||
let mut builder =
|
||||
BlockContainerBuilder::new(context, &anonymous_info, self.text_decoration_line);
|
||||
|
||||
let propagated_data = self.propagated_data.disallowing_percentage_table_columns();
|
||||
let mut builder = BlockContainerBuilder::new(context, &anonymous_info, propagated_data);
|
||||
|
||||
for cell_content in self.current_anonymous_cell_content.drain(..) {
|
||||
match cell_content {
|
||||
|
@ -1021,13 +1034,15 @@ where
|
|||
(rowspan, colspan)
|
||||
});
|
||||
|
||||
let propagated_data =
|
||||
self.propagated_data.disallowing_percentage_table_columns();
|
||||
let contents = match contents.try_into() {
|
||||
Ok(non_replaced_contents) => {
|
||||
BlockFormattingContext::construct(
|
||||
self.table_traversal.context,
|
||||
info,
|
||||
non_replaced_contents,
|
||||
self.text_decoration_line,
|
||||
propagated_data,
|
||||
false, /* is_list_item */
|
||||
)
|
||||
},
|
||||
|
|
|
@ -646,12 +646,51 @@ impl<'a> TableLayout<'a> {
|
|||
// https://drafts.csswg.org/css-tables/#gridmax:
|
||||
// > The row/column-grid width maximum (GRIDMAX) width is the sum of the max-content width of
|
||||
// > all the columns plus cell spacing or borders.
|
||||
let mut grid_min_max = self
|
||||
.columns
|
||||
.iter()
|
||||
.fold(ContentSizes::zero(), |result, measure| {
|
||||
result + measure.content_sizes
|
||||
});
|
||||
//
|
||||
// The specification doesn't say what to do with columns with percentages, so we follow the
|
||||
// approach that LayoutNG takes here. We try to figure out the size contribution
|
||||
// of the percentage columns, by working backward to find the calculated
|
||||
// percentage of non-percent columns and using that to calculate the size of the
|
||||
// percent columns.
|
||||
let mut largest_percentage_column_max_size = Au::zero();
|
||||
let mut percent_sum = 0.;
|
||||
let mut non_percent_columns_max_sum = Au::zero();
|
||||
let mut grid_min_max = ContentSizes::zero();
|
||||
for column in self.columns.iter() {
|
||||
match column.percentage {
|
||||
Some(percentage) if !percentage.is_zero() => {
|
||||
largest_percentage_column_max_size.max_assign(
|
||||
column
|
||||
.content_sizes
|
||||
.max_content
|
||||
.scale_by(1.0 / percentage.0),
|
||||
);
|
||||
percent_sum += percentage.0;
|
||||
},
|
||||
_ => {
|
||||
non_percent_columns_max_sum += column.content_sizes.max_content;
|
||||
},
|
||||
}
|
||||
|
||||
grid_min_max += column.content_sizes;
|
||||
}
|
||||
|
||||
grid_min_max
|
||||
.max_content
|
||||
.max_assign(largest_percentage_column_max_size);
|
||||
|
||||
// Do not take into account percentage of columns when this table is a descendant
|
||||
// of a flex, grid, or table container. These modes with percentage columns can
|
||||
// cause inline width to become infinitely wide.
|
||||
if !percent_sum.is_zero() &&
|
||||
self.table
|
||||
.percentage_columns_allowed_for_inline_content_sizes
|
||||
{
|
||||
let total_inline_size =
|
||||
non_percent_columns_max_sum.scale_by(1.0 / (1.0 - percent_sum.min(1.0)));
|
||||
grid_min_max.max_content.max_assign(total_inline_size);
|
||||
}
|
||||
|
||||
assert!(
|
||||
grid_min_max.min_content <= grid_min_max.max_content,
|
||||
"GRIDMAX should never be smaller than GRIDMIN {:?}",
|
||||
|
|
|
@ -130,6 +130,9 @@ pub struct Table {
|
|||
|
||||
/// Whether or not this Table is anonymous.
|
||||
anonymous: bool,
|
||||
|
||||
/// Whether percentage columns are taken into account during inline content sizes calculation.
|
||||
percentage_columns_allowed_for_inline_content_sizes: bool,
|
||||
}
|
||||
|
||||
impl Table {
|
||||
|
@ -137,6 +140,7 @@ impl Table {
|
|||
style: Arc<ComputedValues>,
|
||||
grid_style: Arc<ComputedValues>,
|
||||
base_fragment_info: BaseFragmentInfo,
|
||||
percentage_columns_allowed_for_inline_content_sizes: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
style,
|
||||
|
@ -150,6 +154,7 @@ impl Table {
|
|||
slots: Vec::new(),
|
||||
size: TableSize::zero(),
|
||||
anonymous: false,
|
||||
percentage_columns_allowed_for_inline_content_sizes,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ use std::fmt;
|
|||
use app_units::Au;
|
||||
use servo_arc::Arc;
|
||||
use style::properties::ComputedValues;
|
||||
use style::values::computed::TextDecorationLine;
|
||||
use stylo_taffy::TaffyStyloStyle;
|
||||
|
||||
use crate::cell::ArcRefCell;
|
||||
|
@ -19,6 +18,7 @@ use crate::dom_traversal::{NodeAndStyleInfo, NonReplacedContents};
|
|||
use crate::formatting_contexts::IndependentFormattingContext;
|
||||
use crate::fragment_tree::Fragment;
|
||||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
||||
use crate::PropagatedBoxTreeData;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct TaffyContainer {
|
||||
|
@ -31,11 +31,10 @@ impl TaffyContainer {
|
|||
context: &LayoutContext,
|
||||
info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
|
||||
contents: NonReplacedContents,
|
||||
propagated_text_decoration_line: TextDecorationLine,
|
||||
propagated_data: PropagatedBoxTreeData,
|
||||
) -> Self {
|
||||
let text_decoration_line =
|
||||
propagated_text_decoration_line | info.style.clone_text_decoration_line();
|
||||
let mut builder = ModernContainerBuilder::new(context, info, text_decoration_line);
|
||||
let mut builder =
|
||||
ModernContainerBuilder::new(context, info, propagated_data.union(&info.style));
|
||||
contents.traverse(context, info, &mut builder);
|
||||
let items = builder.finish();
|
||||
|
||||
|
|
2
tests/wpt/meta/MANIFEST.json
vendored
2
tests/wpt/meta/MANIFEST.json
vendored
|
@ -415973,7 +415973,7 @@
|
|||
]
|
||||
},
|
||||
"table-as-item-percent-width-cell-001-ref.html": [
|
||||
"2f40b6c49fdcee593a160c82c381d4c14f377a38",
|
||||
"b8831e20e761d79ff8ee6e2bfc2a6e1243ca5f7a",
|
||||
[]
|
||||
],
|
||||
"table-item-flex-percentage-min-width-ref.html": [
|
||||
|
|
|
@ -14,9 +14,6 @@
|
|||
[main table 8]
|
||||
expected: FAIL
|
||||
|
||||
[main table 12]
|
||||
expected: FAIL
|
||||
|
||||
[main table 9]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[percent-width-cell-dynamic.html]
|
||||
expected: FAIL
|
|
@ -1,3 +0,0 @@
|
|||
[percent-width-ignored-002.tentative.html]
|
||||
[#stf 1]
|
||||
expected: FAIL
|
|
@ -1,7 +1,4 @@
|
|||
[table-model-fixup.html]
|
||||
[2.1. An anonymous table-row box must be generated around each sequence of consecutive children of a table-root box which are not proper table child boxes. (1/2)]
|
||||
expected: FAIL
|
||||
|
||||
[2.2. An anonymous table-row box must be generated around each sequence of consecutive children of a table-row-grouping box which are not table-row boxes. (1/3)]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -4,6 +4,3 @@
|
|||
|
||||
[table 4]
|
||||
expected: FAIL
|
||||
|
||||
[table 6]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,42 +1,9 @@
|
|||
[colspan-redistribution.html]
|
||||
[table 1]
|
||||
expected: FAIL
|
||||
|
||||
[table 2]
|
||||
expected: FAIL
|
||||
|
||||
[table 3]
|
||||
expected: FAIL
|
||||
|
||||
[table 6]
|
||||
expected: FAIL
|
||||
|
||||
[table 14]
|
||||
expected: FAIL
|
||||
|
||||
[table 15]
|
||||
expected: FAIL
|
||||
|
||||
[table 16]
|
||||
expected: FAIL
|
||||
|
||||
[table 17]
|
||||
expected: FAIL
|
||||
|
||||
[table 20]
|
||||
expected: FAIL
|
||||
|
||||
[table 22]
|
||||
expected: FAIL
|
||||
|
||||
[table 26]
|
||||
expected: FAIL
|
||||
|
||||
[table 27]
|
||||
expected: FAIL
|
||||
|
||||
[table 28]
|
||||
expected: FAIL
|
||||
|
||||
[table 8]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,28 +1,4 @@
|
|||
[column-widths.html]
|
||||
[table 14]
|
||||
expected: FAIL
|
||||
|
||||
[table 19]
|
||||
expected: FAIL
|
||||
|
||||
[table 21]
|
||||
expected: FAIL
|
||||
|
||||
[table 22]
|
||||
expected: FAIL
|
||||
|
||||
[table 23]
|
||||
expected: FAIL
|
||||
|
||||
[table 25]
|
||||
expected: FAIL
|
||||
|
||||
[table 26]
|
||||
expected: FAIL
|
||||
|
||||
[table 30]
|
||||
expected: FAIL
|
||||
|
||||
[table 32]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
[table-minmax.html]
|
||||
[table 2]
|
||||
expected: FAIL
|
||||
|
||||
[table 1]
|
||||
expected: FAIL
|
||||
|
||||
[table 13]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
[table-width-redistribution.html]
|
||||
[table 5]
|
||||
expected: FAIL
|
||||
|
||||
[table 6]
|
||||
expected: FAIL
|
||||
|
||||
[table 20]
|
||||
expected: FAIL
|
||||
|
||||
[table 22]
|
||||
[table 4]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,15 +1,3 @@
|
|||
[td-box-sizing-001.html]
|
||||
[table 1]
|
||||
expected: FAIL
|
||||
|
||||
[table 2]
|
||||
expected: FAIL
|
||||
|
||||
[table 9]
|
||||
expected: FAIL
|
||||
|
||||
[table 10]
|
||||
expected: FAIL
|
||||
|
||||
[table 11]
|
||||
expected: FAIL
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
width: 200px;
|
||||
border: 1px solid black;
|
||||
}
|
||||
table { width: max-content; }
|
||||
table { width: min-content; }
|
||||
td {
|
||||
background-color: cyan;
|
||||
width: 100%;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue