diff options
author | Martin Robinson <mrobinson@igalia.com> | 2024-07-03 20:24:19 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-03 18:24:19 +0000 |
commit | 959ffad99a57f5f8f0554fed0983317577ae8290 (patch) | |
tree | b39a61902cdb8d2bf648b27469ea69dbdcb5aed4 /components/layout_2020/table/construct.rs | |
parent | f8e4ae60401358ac6adaa480e63c587f9f8293a2 (diff) | |
download | servo-959ffad99a57f5f8f0554fed0983317577ae8290.tar.gz servo-959ffad99a57f5f8f0554fed0983317577ae8290.zip |
layout: Add support for table captions (#32657)
This adds initial support for table captions. To do this, the idea of
the table wrapper becomes a bit more concrete. Even so, the wrapper is
still reponsible for allocating space for the grid's border and padding,
as those properties are specified on the wrapper and not grid in CSS.
In order to account for this weirdness of HTML/CSS captions and grid are
now laid out and placed with a negative offset in the table wrapper
content rect.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Diffstat (limited to 'components/layout_2020/table/construct.rs')
-rw-r--r-- | components/layout_2020/table/construct.rs | 62 |
1 files changed, 48 insertions, 14 deletions
diff --git a/components/layout_2020/table/construct.rs b/components/layout_2020/table/construct.rs index fd2441daf18..9be0331aba1 100644 --- a/components/layout_2020/table/construct.rs +++ b/components/layout_2020/table/construct.rs @@ -15,8 +15,8 @@ use style::str::char_is_whitespace; use style::values::specified::TextDecorationLine; use super::{ - Table, TableSlot, TableSlotCell, TableSlotCoordinates, TableSlotOffset, TableTrack, - TableTrackGroup, TableTrackGroupType, + Table, TableCaption, TableSlot, TableSlotCell, TableSlotCoordinates, TableSlotOffset, + TableTrack, TableTrackGroup, TableTrackGroupType, }; use crate::context::LayoutContext; use crate::dom::{BoxSlot, NodeExt}; @@ -73,12 +73,14 @@ impl Table { pub(crate) fn construct<'dom>( context: &LayoutContext, info: &NodeAndStyleInfo<impl NodeExt<'dom>>, + grid_style: Arc<ComputedValues>, contents: NonReplacedContents, propagated_text_decoration_line: TextDecorationLine, ) -> Self { let text_decoration_line = propagated_text_decoration_line | info.style.clone_text_decoration_line(); - let mut traversal = TableBuilderTraversal::new(context, info, text_decoration_line); + let mut traversal = + TableBuilderTraversal::new(context, info, grid_style, text_decoration_line); contents.traverse(context, info, &mut traversal); traversal.finish() } @@ -92,7 +94,7 @@ impl Table { where Node: crate::dom::NodeExt<'dom>, { - let anonymous_style = context + let grid_and_wrapper_style = context .shared_context() .stylist .style_for_anonymous::<Node::ConcreteElement>( @@ -100,10 +102,14 @@ impl Table { &PseudoElement::ServoAnonymousTable, &parent_info.style, ); - let anonymous_info = parent_info.new_anonymous(anonymous_style.clone()); + let anonymous_info = parent_info.new_anonymous(grid_and_wrapper_style.clone()); - let mut table_builder = - TableBuilderTraversal::new(context, &anonymous_info, propagated_text_decoration_line); + let mut table_builder = TableBuilderTraversal::new( + context, + &anonymous_info, + grid_and_wrapper_style.clone(), + propagated_text_decoration_line, + ); for content in contents { match content { @@ -128,7 +134,7 @@ impl Table { IndependentFormattingContext::NonReplaced(NonReplacedFormattingContext { base_fragment_info: (&anonymous_info).into(), - style: anonymous_style, + style: grid_and_wrapper_style, content_sizes: None, contents: NonReplacedFormattingContextContents::Table(table), }) @@ -229,15 +235,23 @@ pub struct TableBuilder { } impl TableBuilder { - pub(super) fn new(style: Arc<ComputedValues>) -> Self { + pub(super) fn new( + style: Arc<ComputedValues>, + grid_style: Arc<ComputedValues>, + base_fragment_info: BaseFragmentInfo, + ) -> Self { Self { - table: Table::new(style), + table: Table::new(style, grid_style, base_fragment_info), incoming_rowspans: Vec::new(), } } pub fn new_for_tests() -> Self { - Self::new(ComputedValues::initial_values().to_arc()) + Self::new( + ComputedValues::initial_values().to_arc(), + ComputedValues::initial_values().to_arc(), + BaseFragmentInfo::anonymous(), + ) } pub fn last_row_index_in_row_group_at_row_n(&self, n: usize) -> usize { @@ -622,13 +636,14 @@ where pub(crate) fn new( context: &'style LayoutContext<'style>, info: &'style NodeAndStyleInfo<Node>, + grid_style: Arc<ComputedValues>, text_decoration_line: TextDecorationLine, ) -> Self { TableBuilderTraversal { context, info, current_text_decoration_line: text_decoration_line, - builder: TableBuilder::new(info.style.clone()), + builder: TableBuilder::new(info.style.clone(), grid_style, info.into()), current_anonymous_row_content: Vec::new(), current_row_group_index: None, } @@ -825,9 +840,28 @@ where ::std::mem::forget(box_slot); }, DisplayLayoutInternal::TableCaption => { - // TODO: Handle table captions. + let contents = match contents.try_into() { + Ok(non_replaced_contents) => { + BlockFormattingContext::construct( + self.context, + info, + non_replaced_contents, + self.current_text_decoration_line, + false, /* is_list_item */ + ) + }, + Err(_replaced) => { + unreachable!("Replaced should not have a LayoutInternal display type."); + }, + }; + self.builder.table.captions.push(TableCaption { + contents, + style: info.style.clone(), + base_fragment_info: info.into(), + }); + // We are doing this until we have actually set a Box for this `BoxSlot`. - ::std::mem::forget(box_slot); + ::std::mem::forget(box_slot) }, DisplayLayoutInternal::TableCell => { self.current_anonymous_row_content |