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 std::borrow::Cow;
|
||||||
|
|
||||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||||
use style::values::computed::TextDecorationLine;
|
|
||||||
|
|
||||||
use crate::context::LayoutContext;
|
use crate::context::LayoutContext;
|
||||||
use crate::dom::{BoxSlot, NodeExt};
|
use crate::dom::{BoxSlot, NodeExt};
|
||||||
|
@ -20,12 +19,13 @@ use crate::formatting_contexts::{
|
||||||
};
|
};
|
||||||
use crate::layout_box_base::LayoutBoxBase;
|
use crate::layout_box_base::LayoutBoxBase;
|
||||||
use crate::style_ext::DisplayGeneratingBox;
|
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> {
|
pub(crate) struct ModernContainerBuilder<'a, 'dom, Node> {
|
||||||
context: &'a LayoutContext<'a>,
|
context: &'a LayoutContext<'a>,
|
||||||
info: &'a NodeAndStyleInfo<Node>,
|
info: &'a NodeAndStyleInfo<Node>,
|
||||||
text_decoration_line: TextDecorationLine,
|
propagated_data: PropagatedBoxTreeData,
|
||||||
contiguous_text_runs: Vec<ModernContainerTextRun<'dom, Node>>,
|
contiguous_text_runs: Vec<ModernContainerTextRun<'dom, Node>>,
|
||||||
/// To be run in parallel with rayon in `finish`
|
/// To be run in parallel with rayon in `finish`
|
||||||
jobs: Vec<ModernContainerJob<'dom, Node>>,
|
jobs: Vec<ModernContainerJob<'dom, Node>>,
|
||||||
|
@ -108,12 +108,12 @@ where
|
||||||
pub fn new(
|
pub fn new(
|
||||||
context: &'a LayoutContext<'a>,
|
context: &'a LayoutContext<'a>,
|
||||||
info: &'a NodeAndStyleInfo<Node>,
|
info: &'a NodeAndStyleInfo<Node>,
|
||||||
text_decoration_line: TextDecorationLine,
|
propagated_data: PropagatedBoxTreeData,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
ModernContainerBuilder {
|
ModernContainerBuilder {
|
||||||
context,
|
context,
|
||||||
info,
|
info,
|
||||||
text_decoration_line,
|
propagated_data: propagated_data.disallowing_percentage_table_columns(),
|
||||||
contiguous_text_runs: Vec::new(),
|
contiguous_text_runs: Vec::new(),
|
||||||
jobs: Vec::new(),
|
jobs: Vec::new(),
|
||||||
has_text_runs: false,
|
has_text_runs: false,
|
||||||
|
@ -164,7 +164,7 @@ where
|
||||||
|
|
||||||
let inline_formatting_context = inline_formatting_context_builder.finish(
|
let inline_formatting_context = inline_formatting_context_builder.finish(
|
||||||
self.context,
|
self.context,
|
||||||
self.text_decoration_line,
|
self.propagated_data,
|
||||||
true, /* has_first_formatted_line */
|
true, /* has_first_formatted_line */
|
||||||
false, /* is_single_line_text_box */
|
false, /* is_single_line_text_box */
|
||||||
self.info.style.writing_mode.to_bidi_level(),
|
self.info.style.writing_mode.to_bidi_level(),
|
||||||
|
@ -195,17 +195,21 @@ where
|
||||||
box_slot,
|
box_slot,
|
||||||
} => {
|
} => {
|
||||||
let is_abspos = info.style.get_box().position.is_absolutely_positioned();
|
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(
|
let formatting_context = IndependentFormattingContext::construct(
|
||||||
self.context,
|
self.context,
|
||||||
&info,
|
&info,
|
||||||
display.display_inside(),
|
display.display_inside(),
|
||||||
contents,
|
contents,
|
||||||
// Text decorations are not propagated to any out-of-flow descendants.
|
propagated_data,
|
||||||
if is_abspos {
|
|
||||||
TextDecorationLine::NONE
|
|
||||||
} else {
|
|
||||||
self.text_decoration_line
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if is_abspos {
|
if is_abspos {
|
||||||
|
|
|
@ -12,7 +12,6 @@ use style::properties::longhands::flex_wrap::computed_value::T as FlexWrap;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::values::computed::{AlignContent, JustifyContent};
|
use style::values::computed::{AlignContent, JustifyContent};
|
||||||
use style::values::specified::align::AlignFlags;
|
use style::values::specified::align::AlignFlags;
|
||||||
use style::values::specified::text::TextDecorationLine;
|
|
||||||
|
|
||||||
use crate::cell::ArcRefCell;
|
use crate::cell::ArcRefCell;
|
||||||
use crate::construct_modern::{ModernContainerBuilder, ModernItemKind};
|
use crate::construct_modern::{ModernContainerBuilder, ModernItemKind};
|
||||||
|
@ -22,7 +21,7 @@ use crate::dom_traversal::{NodeAndStyleInfo, NonReplacedContents};
|
||||||
use crate::formatting_contexts::{IndependentFormattingContext, IndependentLayout};
|
use crate::formatting_contexts::{IndependentFormattingContext, IndependentLayout};
|
||||||
use crate::fragment_tree::BaseFragmentInfo;
|
use crate::fragment_tree::BaseFragmentInfo;
|
||||||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
||||||
use crate::ContainingBlock;
|
use crate::{ContainingBlock, PropagatedBoxTreeData};
|
||||||
|
|
||||||
mod geom;
|
mod geom;
|
||||||
mod layout;
|
mod layout;
|
||||||
|
@ -102,12 +101,10 @@ impl FlexContainer {
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
|
info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
|
||||||
contents: NonReplacedContents,
|
contents: NonReplacedContents,
|
||||||
propagated_text_decoration_line: TextDecorationLine,
|
propagated_data: PropagatedBoxTreeData,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let text_decoration_line =
|
let mut builder =
|
||||||
propagated_text_decoration_line | info.style.clone_text_decoration_line();
|
ModernContainerBuilder::new(context, info, propagated_data.union(&info.style));
|
||||||
|
|
||||||
let mut builder = ModernContainerBuilder::new(context, info, text_decoration_line);
|
|
||||||
contents.traverse(context, info, &mut builder);
|
contents.traverse(context, info, &mut builder);
|
||||||
let items = builder.finish();
|
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::properties::ComputedValues;
|
||||||
use style::selector_parser::PseudoElement;
|
use style::selector_parser::PseudoElement;
|
||||||
use style::str::char_is_whitespace;
|
use style::str::char_is_whitespace;
|
||||||
use style::values::specified::text::TextDecorationLine;
|
|
||||||
|
|
||||||
use super::inline::construct::InlineFormattingContextBuilder;
|
use super::inline::construct::InlineFormattingContextBuilder;
|
||||||
use super::inline::inline_box::InlineBox;
|
use super::inline::inline_box::InlineBox;
|
||||||
|
@ -30,13 +29,14 @@ use crate::layout_box_base::LayoutBoxBase;
|
||||||
use crate::positioned::AbsolutelyPositionedBox;
|
use crate::positioned::AbsolutelyPositionedBox;
|
||||||
use crate::style_ext::{ComputedValuesExt, DisplayGeneratingBox, DisplayInside, DisplayOutside};
|
use crate::style_ext::{ComputedValuesExt, DisplayGeneratingBox, DisplayInside, DisplayOutside};
|
||||||
use crate::table::{AnonymousTableContent, Table};
|
use crate::table::{AnonymousTableContent, Table};
|
||||||
|
use crate::PropagatedBoxTreeData;
|
||||||
|
|
||||||
impl BlockFormattingContext {
|
impl BlockFormattingContext {
|
||||||
pub(crate) fn construct<'dom, Node>(
|
pub(crate) fn construct<'dom, Node>(
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
info: &NodeAndStyleInfo<Node>,
|
info: &NodeAndStyleInfo<Node>,
|
||||||
contents: NonReplacedContents,
|
contents: NonReplacedContents,
|
||||||
propagated_text_decoration_line: TextDecorationLine,
|
propagated_data: PropagatedBoxTreeData,
|
||||||
is_list_item: bool,
|
is_list_item: bool,
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
|
@ -46,7 +46,7 @@ impl BlockFormattingContext {
|
||||||
context,
|
context,
|
||||||
info,
|
info,
|
||||||
contents,
|
contents,
|
||||||
propagated_text_decoration_line,
|
propagated_data,
|
||||||
is_list_item,
|
is_list_item,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,7 @@ impl BlockFormattingContext {
|
||||||
struct BlockLevelJob<'dom, Node> {
|
struct BlockLevelJob<'dom, Node> {
|
||||||
info: NodeAndStyleInfo<Node>,
|
info: NodeAndStyleInfo<Node>,
|
||||||
box_slot: BoxSlot<'dom>,
|
box_slot: BoxSlot<'dom>,
|
||||||
|
propagated_data: PropagatedBoxTreeData,
|
||||||
kind: BlockLevelCreator,
|
kind: BlockLevelCreator,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +72,6 @@ enum BlockLevelCreator {
|
||||||
Independent {
|
Independent {
|
||||||
display_inside: DisplayInside,
|
display_inside: DisplayInside,
|
||||||
contents: Contents,
|
contents: Contents,
|
||||||
propagated_text_decoration_line: TextDecorationLine,
|
|
||||||
},
|
},
|
||||||
OutOfFlowAbsolutelyPositionedBox {
|
OutOfFlowAbsolutelyPositionedBox {
|
||||||
display_inside: DisplayInside,
|
display_inside: DisplayInside,
|
||||||
|
@ -100,7 +100,7 @@ enum IntermediateBlockContainer {
|
||||||
InlineFormattingContext(BlockContainer),
|
InlineFormattingContext(BlockContainer),
|
||||||
Deferred {
|
Deferred {
|
||||||
contents: NonReplacedContents,
|
contents: NonReplacedContents,
|
||||||
propagated_text_decoration_line: TextDecorationLine,
|
propagated_data: PropagatedBoxTreeData,
|
||||||
is_list_item: bool,
|
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`.
|
/// be considered the first line for the purposes of `text-indent`.
|
||||||
have_already_seen_first_line_for_text_indent: bool,
|
have_already_seen_first_line_for_text_indent: bool,
|
||||||
|
|
||||||
/// The propagated [`TextDecorationLine`].
|
/// The propagated data to use for BoxTree construction.
|
||||||
text_decoration_line: TextDecorationLine,
|
propagated_data: PropagatedBoxTreeData,
|
||||||
|
|
||||||
inline_formatting_context_builder: InlineFormattingContextBuilder,
|
inline_formatting_context_builder: InlineFormattingContextBuilder,
|
||||||
|
|
||||||
|
@ -155,14 +155,13 @@ impl BlockContainer {
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
info: &NodeAndStyleInfo<Node>,
|
info: &NodeAndStyleInfo<Node>,
|
||||||
contents: NonReplacedContents,
|
contents: NonReplacedContents,
|
||||||
propagated_text_decoration_line: TextDecorationLine,
|
propagated_data: PropagatedBoxTreeData,
|
||||||
is_list_item: bool,
|
is_list_item: bool,
|
||||||
) -> BlockContainer
|
) -> BlockContainer
|
||||||
where
|
where
|
||||||
Node: NodeExt<'dom>,
|
Node: NodeExt<'dom>,
|
||||||
{
|
{
|
||||||
let mut builder =
|
let mut builder = BlockContainerBuilder::new(context, info, propagated_data);
|
||||||
BlockContainerBuilder::new(context, info, propagated_text_decoration_line);
|
|
||||||
|
|
||||||
if is_list_item {
|
if is_list_item {
|
||||||
if let Some(marker_contents) = crate::lists::make_marker(context, info) {
|
if let Some(marker_contents) = crate::lists::make_marker(context, info) {
|
||||||
|
@ -189,16 +188,13 @@ where
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
context: &'style LayoutContext,
|
context: &'style LayoutContext,
|
||||||
info: &'style NodeAndStyleInfo<Node>,
|
info: &'style NodeAndStyleInfo<Node>,
|
||||||
propagated_text_decoration_line: TextDecorationLine,
|
propagated_data: PropagatedBoxTreeData,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let text_decoration_line =
|
|
||||||
propagated_text_decoration_line | info.style.clone_text_decoration_line();
|
|
||||||
|
|
||||||
BlockContainerBuilder {
|
BlockContainerBuilder {
|
||||||
context,
|
context,
|
||||||
info,
|
info,
|
||||||
block_level_boxes: Vec::new(),
|
block_level_boxes: Vec::new(),
|
||||||
text_decoration_line,
|
propagated_data: propagated_data.union(&info.style),
|
||||||
have_already_seen_first_line_for_text_indent: false,
|
have_already_seen_first_line_for_text_indent: false,
|
||||||
anonymous_style: None,
|
anonymous_style: None,
|
||||||
anonymous_table_content: Vec::new(),
|
anonymous_table_content: Vec::new(),
|
||||||
|
@ -215,7 +211,7 @@ where
|
||||||
|
|
||||||
if let Some(inline_formatting_context) = self.inline_formatting_context_builder.finish(
|
if let Some(inline_formatting_context) = self.inline_formatting_context_builder.finish(
|
||||||
self.context,
|
self.context,
|
||||||
self.text_decoration_line,
|
self.propagated_data,
|
||||||
!self.have_already_seen_first_line_for_text_indent,
|
!self.have_already_seen_first_line_for_text_indent,
|
||||||
self.info.is_single_line_text_input(),
|
self.info.is_single_line_text_input(),
|
||||||
self.info.style.writing_mode.to_bidi_level(),
|
self.info.style.writing_mode.to_bidi_level(),
|
||||||
|
@ -266,10 +262,9 @@ where
|
||||||
// > Note that text decorations are not propagated to floating and absolutely
|
// > Note that text decorations are not propagated to floating and absolutely
|
||||||
// > positioned descendants, nor to the contents of atomic inline-level descendants
|
// > positioned descendants, nor to the contents of atomic inline-level descendants
|
||||||
// > such as inline blocks and inline tables.
|
// > such as inline blocks and inline tables.
|
||||||
let propagated_text_decoration_line = if inline_table {
|
let propagated_data = match inline_table {
|
||||||
TextDecorationLine::NONE
|
true => self.propagated_data.without_text_decorations(),
|
||||||
} else {
|
false => self.propagated_data,
|
||||||
self.text_decoration_line
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let contents: Vec<AnonymousTableContent<'dom, Node>> =
|
let contents: Vec<AnonymousTableContent<'dom, Node>> =
|
||||||
|
@ -279,12 +274,7 @@ where
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let ifc = Table::construct_anonymous(
|
let ifc = Table::construct_anonymous(self.context, self.info, contents, propagated_data);
|
||||||
self.context,
|
|
||||||
self.info,
|
|
||||||
contents,
|
|
||||||
propagated_text_decoration_line,
|
|
||||||
);
|
|
||||||
|
|
||||||
if inline_table {
|
if inline_table {
|
||||||
self.inline_formatting_context_builder.push_atomic(ifc);
|
self.inline_formatting_context_builder.push_atomic(ifc);
|
||||||
|
@ -296,6 +286,7 @@ where
|
||||||
info: anonymous_info,
|
info: anonymous_info,
|
||||||
box_slot: BoxSlot::dummy(),
|
box_slot: BoxSlot::dummy(),
|
||||||
kind: BlockLevelCreator::AnonymousTable { table_block },
|
kind: BlockLevelCreator::AnonymousTable { table_block },
|
||||||
|
propagated_data,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,6 +409,7 @@ where
|
||||||
info: info.clone(),
|
info: info.clone(),
|
||||||
box_slot: BoxSlot::dummy(),
|
box_slot: BoxSlot::dummy(),
|
||||||
kind: BlockLevelCreator::OutsideMarker { contents },
|
kind: BlockLevelCreator::OutsideMarker { contents },
|
||||||
|
propagated_data: self.propagated_data.without_text_decorations(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,7 +431,7 @@ where
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
// Text decorations are not propagated to atomic inline-level descendants.
|
// Text decorations are not propagated to atomic inline-level descendants.
|
||||||
TextDecorationLine::NONE,
|
self.propagated_data.without_text_decorations(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
box_slot.set(LayoutBox::InlineLevel(atomic));
|
box_slot.set(LayoutBox::InlineLevel(atomic));
|
||||||
|
@ -489,7 +481,7 @@ where
|
||||||
.inline_formatting_context_builder
|
.inline_formatting_context_builder
|
||||||
.split_around_block_and_finish(
|
.split_around_block_and_finish(
|
||||||
self.context,
|
self.context,
|
||||||
self.text_decoration_line,
|
self.propagated_data,
|
||||||
!self.have_already_seen_first_line_for_text_indent,
|
!self.have_already_seen_first_line_for_text_indent,
|
||||||
self.info.style.writing_mode.to_bidi_level(),
|
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);
|
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 {
|
let kind = match contents {
|
||||||
Contents::NonReplaced(contents) => match display_inside {
|
Contents::NonReplaced(contents) => match display_inside {
|
||||||
DisplayInside::Flow { is_list_item }
|
DisplayInside::Flow { is_list_item }
|
||||||
|
@ -506,7 +498,7 @@ where
|
||||||
BlockLevelCreator::SameFormattingContextBlock(
|
BlockLevelCreator::SameFormattingContextBlock(
|
||||||
IntermediateBlockContainer::Deferred {
|
IntermediateBlockContainer::Deferred {
|
||||||
contents,
|
contents,
|
||||||
propagated_text_decoration_line,
|
propagated_data,
|
||||||
is_list_item,
|
is_list_item,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -514,7 +506,6 @@ where
|
||||||
_ => BlockLevelCreator::Independent {
|
_ => BlockLevelCreator::Independent {
|
||||||
display_inside,
|
display_inside,
|
||||||
contents: contents.into(),
|
contents: contents.into(),
|
||||||
propagated_text_decoration_line,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Contents::Replaced(contents) => {
|
Contents::Replaced(contents) => {
|
||||||
|
@ -522,7 +513,6 @@ where
|
||||||
BlockLevelCreator::Independent {
|
BlockLevelCreator::Independent {
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
propagated_text_decoration_line,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -530,6 +520,7 @@ where
|
||||||
info: info.clone(),
|
info: info.clone(),
|
||||||
box_slot,
|
box_slot,
|
||||||
kind,
|
kind,
|
||||||
|
propagated_data,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Any block also counts as the first line for the purposes of text indent. Even if
|
// Any block also counts as the first line for the purposes of text indent. Even if
|
||||||
|
@ -565,6 +556,7 @@ where
|
||||||
info: info.clone(),
|
info: info.clone(),
|
||||||
box_slot,
|
box_slot,
|
||||||
kind,
|
kind,
|
||||||
|
propagated_data: self.propagated_data.without_text_decorations(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,6 +575,7 @@ where
|
||||||
info,
|
info,
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
|
self.propagated_data,
|
||||||
));
|
));
|
||||||
box_slot.set(LayoutBox::InlineLevel(inline_level_box));
|
box_slot.set(LayoutBox::InlineLevel(inline_level_box));
|
||||||
return;
|
return;
|
||||||
|
@ -596,13 +589,14 @@ where
|
||||||
info: info.clone(),
|
info: info.clone(),
|
||||||
box_slot,
|
box_slot,
|
||||||
kind,
|
kind,
|
||||||
|
propagated_data: self.propagated_data.without_text_decorations(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end_ongoing_inline_formatting_context(&mut self) {
|
fn end_ongoing_inline_formatting_context(&mut self) {
|
||||||
if let Some(inline_formatting_context) = self.inline_formatting_context_builder.finish(
|
if let Some(inline_formatting_context) = self.inline_formatting_context_builder.finish(
|
||||||
self.context,
|
self.context,
|
||||||
self.text_decoration_line,
|
self.propagated_data,
|
||||||
!self.have_already_seen_first_line_for_text_indent,
|
!self.have_already_seen_first_line_for_text_indent,
|
||||||
self.info.is_single_line_text_input(),
|
self.info.is_single_line_text_input(),
|
||||||
self.info.style.writing_mode.to_bidi_level(),
|
self.info.style.writing_mode.to_bidi_level(),
|
||||||
|
@ -638,6 +632,7 @@ where
|
||||||
BlockContainer::InlineFormattingContext(inline_formatting_context),
|
BlockContainer::InlineFormattingContext(inline_formatting_context),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
propagated_data: self.propagated_data,
|
||||||
});
|
});
|
||||||
|
|
||||||
self.have_already_seen_first_line_for_text_indent = true;
|
self.have_already_seen_first_line_for_text_indent = true;
|
||||||
|
@ -663,14 +658,13 @@ where
|
||||||
BlockLevelCreator::Independent {
|
BlockLevelCreator::Independent {
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
propagated_text_decoration_line,
|
|
||||||
} => {
|
} => {
|
||||||
let context = IndependentFormattingContext::construct(
|
let context = IndependentFormattingContext::construct(
|
||||||
context,
|
context,
|
||||||
info,
|
info,
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
propagated_text_decoration_line,
|
self.propagated_data,
|
||||||
);
|
);
|
||||||
ArcRefCell::new(BlockLevelBox::Independent(context))
|
ArcRefCell::new(BlockLevelBox::Independent(context))
|
||||||
},
|
},
|
||||||
|
@ -693,6 +687,7 @@ where
|
||||||
info,
|
info,
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
|
self.propagated_data,
|
||||||
))),
|
))),
|
||||||
BlockLevelCreator::OutsideMarker { contents } => {
|
BlockLevelCreator::OutsideMarker { contents } => {
|
||||||
let marker_style = context
|
let marker_style = context
|
||||||
|
@ -708,7 +703,7 @@ where
|
||||||
context,
|
context,
|
||||||
&info.new_replacing_style(marker_style.clone()),
|
&info.new_replacing_style(marker_style.clone()),
|
||||||
contents,
|
contents,
|
||||||
TextDecorationLine::empty(),
|
self.propagated_data.without_text_decorations(),
|
||||||
false, /* is_list_item */
|
false, /* is_list_item */
|
||||||
);
|
);
|
||||||
ArcRefCell::new(BlockLevelBox::OutsideMarker(OutsideMarker {
|
ArcRefCell::new(BlockLevelBox::OutsideMarker(OutsideMarker {
|
||||||
|
@ -737,15 +732,9 @@ impl IntermediateBlockContainer {
|
||||||
match self {
|
match self {
|
||||||
IntermediateBlockContainer::Deferred {
|
IntermediateBlockContainer::Deferred {
|
||||||
contents,
|
contents,
|
||||||
propagated_text_decoration_line,
|
propagated_data,
|
||||||
is_list_item,
|
is_list_item,
|
||||||
} => BlockContainer::construct(
|
} => BlockContainer::construct(context, info, contents, propagated_data, is_list_item),
|
||||||
context,
|
|
||||||
info,
|
|
||||||
contents,
|
|
||||||
propagated_text_decoration_line,
|
|
||||||
is_list_item,
|
|
||||||
),
|
|
||||||
IntermediateBlockContainer::InlineFormattingContext(block_container) => block_container,
|
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::logical_geometry::WritingMode;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::values::computed::Clear as StyleClear;
|
use style::values::computed::Clear as StyleClear;
|
||||||
use style::values::specified::text::TextDecorationLine;
|
|
||||||
|
|
||||||
use crate::context::LayoutContext;
|
use crate::context::LayoutContext;
|
||||||
use crate::dom::NodeExt;
|
use crate::dom::NodeExt;
|
||||||
|
@ -29,7 +28,7 @@ use crate::fragment_tree::{BoxFragment, CollapsedMargin};
|
||||||
use crate::geom::{LogicalRect, LogicalVec2, ToLogical};
|
use crate::geom::{LogicalRect, LogicalVec2, ToLogical};
|
||||||
use crate::positioned::{relative_adjustement, PositioningContext};
|
use crate::positioned::{relative_adjustement, PositioningContext};
|
||||||
use crate::style_ext::{DisplayInside, PaddingBorderMargin};
|
use crate::style_ext::{DisplayInside, PaddingBorderMargin};
|
||||||
use crate::ContainingBlock;
|
use crate::{ContainingBlock, PropagatedBoxTreeData};
|
||||||
|
|
||||||
/// A floating box.
|
/// A floating box.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -902,6 +901,7 @@ impl FloatBox {
|
||||||
info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
|
info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
|
||||||
display_inside: DisplayInside,
|
display_inside: DisplayInside,
|
||||||
contents: Contents,
|
contents: Contents,
|
||||||
|
propagated_data: PropagatedBoxTreeData,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
contents: IndependentFormattingContext::construct(
|
contents: IndependentFormattingContext::construct(
|
||||||
|
@ -910,7 +910,7 @@ impl FloatBox {
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
// Text decorations are not propagated to any out-of-flow descendants
|
// 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 icu_segmenter::WordSegmenter;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use style::computed_values::white_space_collapse::T as WhiteSpaceCollapse;
|
use style::computed_values::white_space_collapse::T as WhiteSpaceCollapse;
|
||||||
use style::values::computed::TextDecorationLine;
|
|
||||||
use style::values::specified::text::TextTransformCase;
|
use style::values::specified::text::TextTransformCase;
|
||||||
use unicode_bidi::Level;
|
use unicode_bidi::Level;
|
||||||
|
|
||||||
|
@ -22,6 +21,7 @@ use crate::flow::float::FloatBox;
|
||||||
use crate::formatting_contexts::IndependentFormattingContext;
|
use crate::formatting_contexts::IndependentFormattingContext;
|
||||||
use crate::positioned::AbsolutelyPositionedBox;
|
use crate::positioned::AbsolutelyPositionedBox;
|
||||||
use crate::style_ext::ComputedValuesExt;
|
use crate::style_ext::ComputedValuesExt;
|
||||||
|
use crate::PropagatedBoxTreeData;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub(crate) struct InlineFormattingContextBuilder {
|
pub(crate) struct InlineFormattingContextBuilder {
|
||||||
|
@ -271,7 +271,7 @@ impl InlineFormattingContextBuilder {
|
||||||
pub(crate) fn split_around_block_and_finish(
|
pub(crate) fn split_around_block_and_finish(
|
||||||
&mut self,
|
&mut self,
|
||||||
layout_context: &LayoutContext,
|
layout_context: &LayoutContext,
|
||||||
text_decoration_line: TextDecorationLine,
|
propagated_data: PropagatedBoxTreeData,
|
||||||
has_first_formatted_line: bool,
|
has_first_formatted_line: bool,
|
||||||
default_bidi_level: Level,
|
default_bidi_level: Level,
|
||||||
) -> Option<InlineFormattingContext> {
|
) -> Option<InlineFormattingContext> {
|
||||||
|
@ -303,7 +303,7 @@ impl InlineFormattingContextBuilder {
|
||||||
|
|
||||||
inline_builder_from_before_split.finish(
|
inline_builder_from_before_split.finish(
|
||||||
layout_context,
|
layout_context,
|
||||||
text_decoration_line,
|
propagated_data,
|
||||||
has_first_formatted_line,
|
has_first_formatted_line,
|
||||||
/* is_single_line_text_input = */ false,
|
/* is_single_line_text_input = */ false,
|
||||||
default_bidi_level,
|
default_bidi_level,
|
||||||
|
@ -314,7 +314,7 @@ impl InlineFormattingContextBuilder {
|
||||||
pub(crate) fn finish(
|
pub(crate) fn finish(
|
||||||
&mut self,
|
&mut self,
|
||||||
layout_context: &LayoutContext,
|
layout_context: &LayoutContext,
|
||||||
text_decoration_line: TextDecorationLine,
|
propagated_data: PropagatedBoxTreeData,
|
||||||
has_first_formatted_line: bool,
|
has_first_formatted_line: bool,
|
||||||
is_single_line_text_input: bool,
|
is_single_line_text_input: bool,
|
||||||
default_bidi_level: Level,
|
default_bidi_level: Level,
|
||||||
|
@ -329,7 +329,7 @@ impl InlineFormattingContextBuilder {
|
||||||
Some(InlineFormattingContext::new_with_builder(
|
Some(InlineFormattingContext::new_with_builder(
|
||||||
old_builder,
|
old_builder,
|
||||||
layout_context,
|
layout_context,
|
||||||
text_decoration_line,
|
propagated_data,
|
||||||
has_first_formatted_line,
|
has_first_formatted_line,
|
||||||
is_single_line_text_input,
|
is_single_line_text_input,
|
||||||
default_bidi_level,
|
default_bidi_level,
|
||||||
|
|
|
@ -127,7 +127,7 @@ use crate::geom::{LogicalRect, LogicalVec2, ToLogical};
|
||||||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
||||||
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
|
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
|
||||||
use crate::style_ext::{ComputedValuesExt, PaddingBorderMargin};
|
use crate::style_ext::{ComputedValuesExt, PaddingBorderMargin};
|
||||||
use crate::{ConstraintSpace, ContainingBlock};
|
use crate::{ConstraintSpace, ContainingBlock, PropagatedBoxTreeData};
|
||||||
|
|
||||||
// From gfxFontConstants.h in Firefox.
|
// From gfxFontConstants.h in Firefox.
|
||||||
static FONT_SUBSCRIPT_OFFSET_RATIO: f32 = 0.20;
|
static FONT_SUBSCRIPT_OFFSET_RATIO: f32 = 0.20;
|
||||||
|
@ -1519,7 +1519,7 @@ impl InlineFormattingContext {
|
||||||
pub(super) fn new_with_builder(
|
pub(super) fn new_with_builder(
|
||||||
builder: InlineFormattingContextBuilder,
|
builder: InlineFormattingContextBuilder,
|
||||||
layout_context: &LayoutContext,
|
layout_context: &LayoutContext,
|
||||||
text_decoration_line: TextDecorationLine,
|
propagated_data: PropagatedBoxTreeData,
|
||||||
has_first_formatted_line: bool,
|
has_first_formatted_line: bool,
|
||||||
is_single_line_text_input: bool,
|
is_single_line_text_input: bool,
|
||||||
starting_bidi_level: Level,
|
starting_bidi_level: Level,
|
||||||
|
@ -1570,7 +1570,7 @@ impl InlineFormattingContext {
|
||||||
inline_items: builder.inline_items,
|
inline_items: builder.inline_items,
|
||||||
inline_boxes: builder.inline_boxes,
|
inline_boxes: builder.inline_boxes,
|
||||||
font_metrics,
|
font_metrics,
|
||||||
text_decoration_line,
|
text_decoration_line: propagated_data.text_decoration,
|
||||||
has_first_formatted_line,
|
has_first_formatted_line,
|
||||||
contains_floats: builder.contains_floats,
|
contains_floats: builder.contains_floats,
|
||||||
is_single_line_text_input,
|
is_single_line_text_input,
|
||||||
|
|
|
@ -30,7 +30,7 @@ use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
||||||
use crate::replaced::ReplacedContents;
|
use crate::replaced::ReplacedContents;
|
||||||
use crate::style_ext::{ComputedValuesExt, Display, DisplayGeneratingBox, DisplayInside};
|
use crate::style_ext::{ComputedValuesExt, Display, DisplayGeneratingBox, DisplayInside};
|
||||||
use crate::taffy::{TaffyItemBox, TaffyItemBoxInner};
|
use crate::taffy::{TaffyItemBox, TaffyItemBoxInner};
|
||||||
use crate::DefiniteContainingBlock;
|
use crate::{DefiniteContainingBlock, PropagatedBoxTreeData};
|
||||||
|
|
||||||
pub struct BoxTree {
|
pub struct BoxTree {
|
||||||
/// Contains typically exactly one block-level box, which was generated by the root element.
|
/// 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)
|
let contents = ReplacedContents::for_element(root_element, context)
|
||||||
.map_or_else(|| NonReplacedContents::OfElement.into(), Contents::Replaced);
|
.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() {
|
let root_box = if box_style.position.is_absolutely_positioned() {
|
||||||
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(ArcRefCell::new(
|
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(ArcRefCell::new(
|
||||||
AbsolutelyPositionedBox::construct(context, &info, display_inside, contents),
|
AbsolutelyPositionedBox::construct(context, &info, display_inside, contents),
|
||||||
|
@ -299,15 +301,15 @@ fn construct_for_root_element<'dom>(
|
||||||
&info,
|
&info,
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
|
propagated_data,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
let propagated_text_decoration_line = info.style.clone_text_decoration_line();
|
|
||||||
BlockLevelBox::Independent(IndependentFormattingContext::construct(
|
BlockLevelBox::Independent(IndependentFormattingContext::construct(
|
||||||
context,
|
context,
|
||||||
&info,
|
&info,
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
propagated_text_decoration_line,
|
propagated_data,
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ use app_units::Au;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::selector_parser::PseudoElement;
|
use style::selector_parser::PseudoElement;
|
||||||
use style::values::specified::text::TextDecorationLine;
|
|
||||||
|
|
||||||
use crate::context::LayoutContext;
|
use crate::context::LayoutContext;
|
||||||
use crate::dom::NodeExt;
|
use crate::dom::NodeExt;
|
||||||
|
@ -24,7 +23,9 @@ use crate::sizing::{self, ComputeInlineContentSizes, InlineContentSizesResult};
|
||||||
use crate::style_ext::{AspectRatio, DisplayInside, LayoutStyle};
|
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, PropagatedBoxTreeData,
|
||||||
|
};
|
||||||
|
|
||||||
/// <https://drafts.csswg.org/css-display/#independent-formatting-context>
|
/// <https://drafts.csswg.org/css-display/#independent-formatting-context>
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -102,7 +103,7 @@ impl IndependentFormattingContext {
|
||||||
node_and_style_info: &NodeAndStyleInfo<Node>,
|
node_and_style_info: &NodeAndStyleInfo<Node>,
|
||||||
display_inside: DisplayInside,
|
display_inside: DisplayInside,
|
||||||
contents: Contents,
|
contents: Contents,
|
||||||
propagated_text_decoration_line: TextDecorationLine,
|
propagated_data: PropagatedBoxTreeData,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut base_fragment_info: BaseFragmentInfo = node_and_style_info.into();
|
let mut base_fragment_info: BaseFragmentInfo = node_and_style_info.into();
|
||||||
|
|
||||||
|
@ -115,7 +116,7 @@ impl IndependentFormattingContext {
|
||||||
context,
|
context,
|
||||||
node_and_style_info,
|
node_and_style_info,
|
||||||
non_replaced_contents,
|
non_replaced_contents,
|
||||||
propagated_text_decoration_line,
|
propagated_data,
|
||||||
is_list_item,
|
is_list_item,
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
|
@ -124,7 +125,7 @@ impl IndependentFormattingContext {
|
||||||
context,
|
context,
|
||||||
node_and_style_info,
|
node_and_style_info,
|
||||||
non_replaced_contents,
|
non_replaced_contents,
|
||||||
propagated_text_decoration_line,
|
propagated_data,
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
DisplayInside::Flex => {
|
DisplayInside::Flex => {
|
||||||
|
@ -132,7 +133,7 @@ impl IndependentFormattingContext {
|
||||||
context,
|
context,
|
||||||
node_and_style_info,
|
node_and_style_info,
|
||||||
non_replaced_contents,
|
non_replaced_contents,
|
||||||
propagated_text_decoration_line,
|
propagated_data,
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
DisplayInside::Table => {
|
DisplayInside::Table => {
|
||||||
|
@ -150,7 +151,7 @@ impl IndependentFormattingContext {
|
||||||
node_and_style_info,
|
node_and_style_info,
|
||||||
table_grid_style,
|
table_grid_style,
|
||||||
non_replaced_contents,
|
non_replaced_contents,
|
||||||
propagated_text_decoration_line,
|
propagated_data,
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,6 +33,7 @@ pub use fragment_tree::FragmentTree;
|
||||||
use geom::AuOrAuto;
|
use geom::AuOrAuto;
|
||||||
use style::logical_geometry::WritingMode;
|
use style::logical_geometry::WritingMode;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
|
use style::values::computed::TextDecorationLine;
|
||||||
|
|
||||||
use crate::geom::{LogicalVec2, SizeConstraint};
|
use crate::geom::{LogicalVec2, SizeConstraint};
|
||||||
use crate::style_ext::AspectRatio;
|
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::logical_geometry::WritingMode;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::values::specified::align::{AlignFlags, AxisDirection};
|
use style::values::specified::align::{AlignFlags, AxisDirection};
|
||||||
use style::values::specified::text::TextDecorationLine;
|
|
||||||
use style::Zero;
|
use style::Zero;
|
||||||
|
|
||||||
use crate::cell::ArcRefCell;
|
use crate::cell::ArcRefCell;
|
||||||
|
@ -32,7 +31,8 @@ use crate::geom::{
|
||||||
use crate::sizing::ContentSizes;
|
use crate::sizing::ContentSizes;
|
||||||
use crate::style_ext::{ComputedValuesExt, ContentBoxSizesAndPBM, DisplayInside};
|
use crate::style_ext::{ComputedValuesExt, ContentBoxSizesAndPBM, DisplayInside};
|
||||||
use crate::{
|
use crate::{
|
||||||
ConstraintSpace, ContainingBlock, ContainingBlockSize, DefiniteContainingBlock, SizeConstraint,
|
ConstraintSpace, ContainingBlock, ContainingBlockSize, DefiniteContainingBlock,
|
||||||
|
PropagatedBoxTreeData, SizeConstraint,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -75,8 +75,10 @@ impl AbsolutelyPositionedBox {
|
||||||
node_info,
|
node_info,
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
// Text decorations are not propagated to any out-of-flow descendants.
|
// Text decorations are not propagated to any out-of-flow descendants. In addition,
|
||||||
TextDecorationLine::NONE,
|
// 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::properties::ComputedValues;
|
||||||
use style::selector_parser::PseudoElement;
|
use style::selector_parser::PseudoElement;
|
||||||
use style::str::char_is_whitespace;
|
use style::str::char_is_whitespace;
|
||||||
use style::values::specified::TextDecorationLine;
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
Table, TableCaption, TableSlot, TableSlotCell, TableSlotCoordinates, TableSlotOffset,
|
Table, TableCaption, TableSlot, TableSlotCell, TableSlotCoordinates, TableSlotOffset,
|
||||||
|
@ -31,6 +30,7 @@ use crate::formatting_contexts::{
|
||||||
use crate::fragment_tree::BaseFragmentInfo;
|
use crate::fragment_tree::BaseFragmentInfo;
|
||||||
use crate::layout_box_base::LayoutBoxBase;
|
use crate::layout_box_base::LayoutBoxBase;
|
||||||
use crate::style_ext::{DisplayGeneratingBox, DisplayLayoutInternal};
|
use crate::style_ext::{DisplayGeneratingBox, DisplayLayoutInternal};
|
||||||
|
use crate::PropagatedBoxTreeData;
|
||||||
|
|
||||||
/// A reference to a slot and its coordinates in the table
|
/// A reference to a slot and its coordinates in the table
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
@ -78,12 +78,14 @@ impl Table {
|
||||||
info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
|
info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
|
||||||
grid_style: Arc<ComputedValues>,
|
grid_style: Arc<ComputedValues>,
|
||||||
contents: NonReplacedContents,
|
contents: NonReplacedContents,
|
||||||
propagated_text_decoration_line: TextDecorationLine,
|
propagated_data: PropagatedBoxTreeData,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let text_decoration_line =
|
let mut traversal = TableBuilderTraversal::new(
|
||||||
propagated_text_decoration_line | info.style.clone_text_decoration_line();
|
context,
|
||||||
let mut traversal =
|
info,
|
||||||
TableBuilderTraversal::new(context, info, grid_style, text_decoration_line);
|
grid_style,
|
||||||
|
propagated_data.union(&info.style),
|
||||||
|
);
|
||||||
contents.traverse(context, info, &mut traversal);
|
contents.traverse(context, info, &mut traversal);
|
||||||
traversal.finish()
|
traversal.finish()
|
||||||
}
|
}
|
||||||
|
@ -92,7 +94,7 @@ impl Table {
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
parent_info: &NodeAndStyleInfo<Node>,
|
parent_info: &NodeAndStyleInfo<Node>,
|
||||||
contents: Vec<AnonymousTableContent<'dom, Node>>,
|
contents: Vec<AnonymousTableContent<'dom, Node>>,
|
||||||
propagated_text_decoration_line: style::values::specified::TextDecorationLine,
|
propagated_data: PropagatedBoxTreeData,
|
||||||
) -> IndependentFormattingContext
|
) -> IndependentFormattingContext
|
||||||
where
|
where
|
||||||
Node: crate::dom::NodeExt<'dom>,
|
Node: crate::dom::NodeExt<'dom>,
|
||||||
|
@ -111,7 +113,7 @@ impl Table {
|
||||||
context,
|
context,
|
||||||
&anonymous_info,
|
&anonymous_info,
|
||||||
grid_and_wrapper_style.clone(),
|
grid_and_wrapper_style.clone(),
|
||||||
propagated_text_decoration_line,
|
propagated_data,
|
||||||
);
|
);
|
||||||
|
|
||||||
for content in contents {
|
for content in contents {
|
||||||
|
@ -242,9 +244,15 @@ impl TableBuilder {
|
||||||
style: Arc<ComputedValues>,
|
style: Arc<ComputedValues>,
|
||||||
grid_style: Arc<ComputedValues>,
|
grid_style: Arc<ComputedValues>,
|
||||||
base_fragment_info: BaseFragmentInfo,
|
base_fragment_info: BaseFragmentInfo,
|
||||||
|
percentage_columns_allowed_for_inline_content_sizes: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
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(),
|
incoming_rowspans: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,6 +264,7 @@ impl TableBuilder {
|
||||||
testing_style.clone(),
|
testing_style.clone(),
|
||||||
testing_style.clone(),
|
testing_style.clone(),
|
||||||
BaseFragmentInfo::anonymous(),
|
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>,
|
context: &'style LayoutContext<'style>,
|
||||||
info: &'style NodeAndStyleInfo<Node>,
|
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.
|
/// 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
|
/// The [`TableBuilder`] for this [`TableBuilderTraversal`]. This is separated
|
||||||
/// into another struct so that we can write unit tests against the builder.
|
/// into another struct so that we can write unit tests against the builder.
|
||||||
|
@ -649,13 +658,18 @@ where
|
||||||
context: &'style LayoutContext<'style>,
|
context: &'style LayoutContext<'style>,
|
||||||
info: &'style NodeAndStyleInfo<Node>,
|
info: &'style NodeAndStyleInfo<Node>,
|
||||||
grid_style: Arc<ComputedValues>,
|
grid_style: Arc<ComputedValues>,
|
||||||
text_decoration_line: TextDecorationLine,
|
propagated_data: PropagatedBoxTreeData,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
TableBuilderTraversal {
|
TableBuilderTraversal {
|
||||||
context,
|
context,
|
||||||
info,
|
info,
|
||||||
current_text_decoration_line: text_decoration_line,
|
current_propagated_data: propagated_data,
|
||||||
builder: TableBuilder::new(info.style.clone(), grid_style, info.into()),
|
builder: TableBuilder::new(
|
||||||
|
info.style.clone(),
|
||||||
|
grid_style,
|
||||||
|
info.into(),
|
||||||
|
propagated_data.allow_percentage_column_in_tables,
|
||||||
|
),
|
||||||
current_anonymous_row_content: Vec::new(),
|
current_anonymous_row_content: Vec::new(),
|
||||||
current_row_group_index: None,
|
current_row_group_index: None,
|
||||||
}
|
}
|
||||||
|
@ -686,7 +700,7 @@ where
|
||||||
);
|
);
|
||||||
let anonymous_info = self.info.new_anonymous(anonymous_style.clone());
|
let anonymous_info = self.info.new_anonymous(anonymous_style.clone());
|
||||||
let mut row_builder =
|
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 {
|
for cell_content in row_content {
|
||||||
match cell_content {
|
match cell_content {
|
||||||
|
@ -758,8 +772,8 @@ where
|
||||||
track_range: next_row_index..next_row_index,
|
track_range: next_row_index..next_row_index,
|
||||||
});
|
});
|
||||||
|
|
||||||
let previous_text_decoration_line = self.current_text_decoration_line;
|
let previous_propagated_data = self.current_propagated_data;
|
||||||
self.current_text_decoration_line |= info.style.clone_text_decoration_line();
|
self.current_propagated_data = self.current_propagated_data.union(&info.style);
|
||||||
|
|
||||||
let new_row_group_index = self.builder.table.row_groups.len() - 1;
|
let new_row_group_index = self.builder.table.row_groups.len() - 1;
|
||||||
self.current_row_group_index = Some(new_row_group_index);
|
self.current_row_group_index = Some(new_row_group_index);
|
||||||
|
@ -772,7 +786,7 @@ where
|
||||||
self.finish_anonymous_row_if_needed();
|
self.finish_anonymous_row_if_needed();
|
||||||
|
|
||||||
self.current_row_group_index = None;
|
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();
|
self.builder.incoming_rowspans.clear();
|
||||||
|
|
||||||
// We are doing this until we have actually set a Box for this `BoxSlot`.
|
// We are doing this until we have actually set a Box for this `BoxSlot`.
|
||||||
|
@ -784,7 +798,7 @@ where
|
||||||
let context = self.context;
|
let context = self.context;
|
||||||
|
|
||||||
let mut row_builder =
|
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(
|
NonReplacedContents::try_from(contents).unwrap().traverse(
|
||||||
context,
|
context,
|
||||||
info,
|
info,
|
||||||
|
@ -857,7 +871,7 @@ where
|
||||||
self.context,
|
self.context,
|
||||||
info,
|
info,
|
||||||
non_replaced_contents,
|
non_replaced_contents,
|
||||||
self.current_text_decoration_line,
|
self.current_propagated_data,
|
||||||
false, /* is_list_item */
|
false, /* is_list_item */
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
|
@ -910,8 +924,8 @@ struct TableRowBuilder<'style, 'builder, 'dom, 'a, Node> {
|
||||||
|
|
||||||
current_anonymous_cell_content: Vec<AnonymousTableContent<'dom, Node>>,
|
current_anonymous_cell_content: Vec<AnonymousTableContent<'dom, Node>>,
|
||||||
|
|
||||||
/// The [`TextDecorationLine`] to use for all children of this row.
|
/// The [`PropagatedBoxTreeData`] to use for all children of this row.
|
||||||
text_decoration_line: TextDecorationLine,
|
propagated_data: PropagatedBoxTreeData,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'style, 'builder, 'dom, 'a, Node: 'dom> TableRowBuilder<'style, 'builder, 'dom, 'a, Node>
|
impl<'style, 'builder, 'dom, 'a, Node: 'dom> TableRowBuilder<'style, 'builder, 'dom, 'a, Node>
|
||||||
|
@ -921,17 +935,15 @@ where
|
||||||
fn new(
|
fn new(
|
||||||
table_traversal: &'builder mut TableBuilderTraversal<'style, 'dom, Node>,
|
table_traversal: &'builder mut TableBuilderTraversal<'style, 'dom, Node>,
|
||||||
info: &'a NodeAndStyleInfo<Node>,
|
info: &'a NodeAndStyleInfo<Node>,
|
||||||
propagated_text_decoration_line: TextDecorationLine,
|
propagated_data: PropagatedBoxTreeData,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
table_traversal.builder.start_row();
|
table_traversal.builder.start_row();
|
||||||
|
|
||||||
let text_decoration_line =
|
|
||||||
propagated_text_decoration_line | info.style.clone_text_decoration_line();
|
|
||||||
TableRowBuilder {
|
TableRowBuilder {
|
||||||
table_traversal,
|
table_traversal,
|
||||||
info,
|
info,
|
||||||
current_anonymous_cell_content: Vec::new(),
|
current_anonymous_cell_content: Vec::new(),
|
||||||
text_decoration_line,
|
propagated_data: propagated_data.union(&info.style),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -957,8 +969,9 @@ where
|
||||||
&self.info.style,
|
&self.info.style,
|
||||||
);
|
);
|
||||||
let anonymous_info = self.info.new_anonymous(anonymous_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(..) {
|
for cell_content in self.current_anonymous_cell_content.drain(..) {
|
||||||
match cell_content {
|
match cell_content {
|
||||||
|
@ -1021,13 +1034,15 @@ where
|
||||||
(rowspan, colspan)
|
(rowspan, colspan)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let propagated_data =
|
||||||
|
self.propagated_data.disallowing_percentage_table_columns();
|
||||||
let contents = match contents.try_into() {
|
let contents = match contents.try_into() {
|
||||||
Ok(non_replaced_contents) => {
|
Ok(non_replaced_contents) => {
|
||||||
BlockFormattingContext::construct(
|
BlockFormattingContext::construct(
|
||||||
self.table_traversal.context,
|
self.table_traversal.context,
|
||||||
info,
|
info,
|
||||||
non_replaced_contents,
|
non_replaced_contents,
|
||||||
self.text_decoration_line,
|
propagated_data,
|
||||||
false, /* is_list_item */
|
false, /* is_list_item */
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
|
@ -646,12 +646,51 @@ impl<'a> TableLayout<'a> {
|
||||||
// https://drafts.csswg.org/css-tables/#gridmax:
|
// https://drafts.csswg.org/css-tables/#gridmax:
|
||||||
// > The row/column-grid width maximum (GRIDMAX) width is the sum of the max-content width of
|
// > 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.
|
// > all the columns plus cell spacing or borders.
|
||||||
let mut grid_min_max = self
|
//
|
||||||
.columns
|
// The specification doesn't say what to do with columns with percentages, so we follow the
|
||||||
.iter()
|
// approach that LayoutNG takes here. We try to figure out the size contribution
|
||||||
.fold(ContentSizes::zero(), |result, measure| {
|
// of the percentage columns, by working backward to find the calculated
|
||||||
result + measure.content_sizes
|
// 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!(
|
assert!(
|
||||||
grid_min_max.min_content <= grid_min_max.max_content,
|
grid_min_max.min_content <= grid_min_max.max_content,
|
||||||
"GRIDMAX should never be smaller than GRIDMIN {:?}",
|
"GRIDMAX should never be smaller than GRIDMIN {:?}",
|
||||||
|
|
|
@ -130,6 +130,9 @@ pub struct Table {
|
||||||
|
|
||||||
/// Whether or not this Table is anonymous.
|
/// Whether or not this Table is anonymous.
|
||||||
anonymous: bool,
|
anonymous: bool,
|
||||||
|
|
||||||
|
/// Whether percentage columns are taken into account during inline content sizes calculation.
|
||||||
|
percentage_columns_allowed_for_inline_content_sizes: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Table {
|
impl Table {
|
||||||
|
@ -137,6 +140,7 @@ impl Table {
|
||||||
style: Arc<ComputedValues>,
|
style: Arc<ComputedValues>,
|
||||||
grid_style: Arc<ComputedValues>,
|
grid_style: Arc<ComputedValues>,
|
||||||
base_fragment_info: BaseFragmentInfo,
|
base_fragment_info: BaseFragmentInfo,
|
||||||
|
percentage_columns_allowed_for_inline_content_sizes: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
style,
|
style,
|
||||||
|
@ -150,6 +154,7 @@ impl Table {
|
||||||
slots: Vec::new(),
|
slots: Vec::new(),
|
||||||
size: TableSize::zero(),
|
size: TableSize::zero(),
|
||||||
anonymous: false,
|
anonymous: false,
|
||||||
|
percentage_columns_allowed_for_inline_content_sizes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ use std::fmt;
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::values::computed::TextDecorationLine;
|
|
||||||
use stylo_taffy::TaffyStyloStyle;
|
use stylo_taffy::TaffyStyloStyle;
|
||||||
|
|
||||||
use crate::cell::ArcRefCell;
|
use crate::cell::ArcRefCell;
|
||||||
|
@ -19,6 +18,7 @@ use crate::dom_traversal::{NodeAndStyleInfo, NonReplacedContents};
|
||||||
use crate::formatting_contexts::IndependentFormattingContext;
|
use crate::formatting_contexts::IndependentFormattingContext;
|
||||||
use crate::fragment_tree::Fragment;
|
use crate::fragment_tree::Fragment;
|
||||||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
||||||
|
use crate::PropagatedBoxTreeData;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct TaffyContainer {
|
pub(crate) struct TaffyContainer {
|
||||||
|
@ -31,11 +31,10 @@ impl TaffyContainer {
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
|
info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
|
||||||
contents: NonReplacedContents,
|
contents: NonReplacedContents,
|
||||||
propagated_text_decoration_line: TextDecorationLine,
|
propagated_data: PropagatedBoxTreeData,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let text_decoration_line =
|
let mut builder =
|
||||||
propagated_text_decoration_line | info.style.clone_text_decoration_line();
|
ModernContainerBuilder::new(context, info, propagated_data.union(&info.style));
|
||||||
let mut builder = ModernContainerBuilder::new(context, info, text_decoration_line);
|
|
||||||
contents.traverse(context, info, &mut builder);
|
contents.traverse(context, info, &mut builder);
|
||||||
let items = builder.finish();
|
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": [
|
"table-as-item-percent-width-cell-001-ref.html": [
|
||||||
"2f40b6c49fdcee593a160c82c381d4c14f377a38",
|
"b8831e20e761d79ff8ee6e2bfc2a6e1243ca5f7a",
|
||||||
[]
|
[]
|
||||||
],
|
],
|
||||||
"table-item-flex-percentage-min-width-ref.html": [
|
"table-item-flex-percentage-min-width-ref.html": [
|
||||||
|
|
|
@ -14,9 +14,6 @@
|
||||||
[main table 8]
|
[main table 8]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[main table 12]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[main table 9]
|
[main table 9]
|
||||||
expected: FAIL
|
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]
|
[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)]
|
[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
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,3 @@
|
||||||
|
|
||||||
[table 4]
|
[table 4]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[table 6]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,42 +1,9 @@
|
||||||
[colspan-redistribution.html]
|
[colspan-redistribution.html]
|
||||||
[table 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[table 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[table 3]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[table 6]
|
[table 6]
|
||||||
expected: FAIL
|
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]
|
[table 26]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[table 27]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[table 28]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[table 8]
|
[table 8]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -1,28 +1,4 @@
|
||||||
[column-widths.html]
|
[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]
|
[table 32]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
[table-minmax.html]
|
[table-minmax.html]
|
||||||
[table 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[table 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[table 13]
|
[table 13]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
[table-width-redistribution.html]
|
[table-width-redistribution.html]
|
||||||
[table 5]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[table 6]
|
[table 6]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[table 20]
|
[table 4]
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[table 22]
|
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -1,15 +1,3 @@
|
||||||
[td-box-sizing-001.html]
|
[td-box-sizing-001.html]
|
||||||
[table 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[table 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[table 9]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[table 10]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[table 11]
|
[table 11]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
width: 200px;
|
width: 200px;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
}
|
}
|
||||||
table { width: max-content; }
|
table { width: min-content; }
|
||||||
td {
|
td {
|
||||||
background-color: cyan;
|
background-color: cyan;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue